Porównuję dwa zapytania w SQL Server 2012. Celem wyboru najlepszego zapytania jest wykorzystanie wszystkich istotnych informacji dostępnych w optymalizatorze zapytań. Oba zapytania dają takie same wyniki; maksymalne zamówienie dla wszystkich klientów.
Czyszczenie puli buforów zostało wykonane przed wykonaniem każdego zapytania za pomocą FREEPROCCACHE i DROPCLEANBUFFERS
Które zapytanie jest najlepszym wyborem na podstawie poniższych informacji?
-- Query 1 - return the maximum order id for a customer
SELECT orderid, custid
FROM Sales.Orders AS O1
WHERE orderid = (SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid);
-- Query 2 - return the maximum order id for a customer
SELECT MAX(orderid), custid
FROM Sales.Orders AS O1
group by custid
order by custid
CZAS STATYSTYCZNY
Zapytanie 1 CZAS STATYSTYCZNY: Czas procesora = 0ms, czas, który upłynął = 24 ms
Zapytanie 2 CZAS STATYSTYCZNY: Czas procesora = 0 ms, czas, który upłynął = 23 ms
STATYSTYKA IO
Zapytanie 1 STATYSTYKI IO: Tabela „Zamówienia”. Liczba skanów 1, logiczne odczyty 5, fizyczne odczyty 2, wyprzedzające odczyty 0, logiczne odczyty 0, lob fizyczne odczyty 0, lob odczyty 0.
Zapytanie 2 STATYSTYKI IO: Tabela „Zamówienia”. Liczba skanów 1, logiczne odczyty 4, fizyczne odczyty 1, odczyt z wyprzedzeniem 8, logiczne odczyty 0, lob fizyczne odczyty 0, odczyt z wyprzedzeniem 0.
Plany wykonania
WYBIERZ właściwości Zapytanie 1
WYBIERZ właściwości Zapytanie 2
Wnioski:
Zapytanie 1
- Koszt partii 48%
- Odczyty logiczne 5
- Odczyty fizyczne 2
- Czytaj dalej Czyta: 0
- Czas procesora: 0ms
- Upływający czas 24ms
- Szacowany koszt poddrzewa: 0,0050276
- CompileCPU: 2
- CompileMemory: 384
- CompileTime: 2
Zapytanie 2
- Koszt partii 52%
- Odczyty logiczne 4
- Odczyty fizyczne 1
- Odczyt z wyprzedzeniem Odczyty: 8
- Czas procesora 0
- Upłynęło 23 ms
- Szacowany koszt poddrzewa: 0,0054782
- CompileCPU: 0
- CompileMemory: 192
- CompileTime: 0
Osobiście, mimo że Kwerenda 2 ma wyższy koszt partii zgodnie z planem graficznym, myślę, że jest bardziej skuteczna niż Kwerenda 1. To dlatego, że kwerenda 2 wymaga mniej logicznych odczytów, ma nieco krótszy czas, który upłynął, wartości compilecpu, kompilememory i kompilacji są niższy. odczyt z wyprzedzeniem wynosi 8 dla zapytania 2 i 0 dla zapytania 1.
Zaktualizuj 12:03
Definicja indeksu klastrowego
ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Indeks nieklastrowany idx_nc_custid
CREATE NONCLUSTERED INDEX [idx_nc_custid] ON [Sales].[Orders]
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO