Ich vergleiche zwei Abfragen in SQL Server 2012. Ziel ist es, alle relevanten Informationen des Abfrageoptimierers für die Auswahl der besten Abfrage zu verwenden. Beide Abfragen führen zu denselben Ergebnissen. die maximale Bestellnummer für alle Kunden.
Das Löschen des Pufferpools wurde vor dem Ausführen jeder Abfrage mit FREEPROCCACHE und DROPCLEANBUFFERS durchgeführt
Welche Abfrage ist unter Verwendung der unten angegebenen Informationen die bessere Wahl?
-- 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
STATISTIKEN ZEIT
Abfrage 1 STATISTIKZEIT: CPU-Zeit = 0 ms, verstrichene Zeit = 24 ms
Abfrage 2 STATISTIKZEIT: CPU-Zeit = 0 ms, verstrichene Zeit = 23 ms
STATISTIKEN IO
Abfrage 1 STATISTICS IO: Tabelle 'Orders'. Scananzahl 1, logische Lesevorgänge 5, physische Lesevorgänge 2, Vorauslesevorgänge 0, logische Lobs-Lesevorgänge 0, physikalische Lobs-Lesevorgänge 0, Lobs-Vorauslesevorgänge 0.
Abfrage 2 STATISTIK IO: Tabelle 'Bestellungen'. Scananzahl 1, logische Lesevorgänge 4, physische Lesevorgänge 1, Vorauslesevorgänge 8, logische Lobs-Lesevorgänge 0, physische Lobs-Lesevorgänge 0, Lobs-Vorauslesevorgänge 0.
Ausführungspläne
SELECT-Eigenschaften Abfrage 1
SELECT Eigenschaften Abfrage 2
Schlussfolgerungen:
Abfrage 1
- Batch-Kosten 48%
- Logische Lesevorgänge 5
- Physische Lesevorgänge 2
- Vorauslesen Liest: 0
- CPU-Zeit: 0ms
- Verstrichene Zeit 24ms
- Geschätzte Teilbaumkosten: 0.0050276
- CompileCPU: 2
- CompileMemory: 384
- CompileTime: 2
Abfrage 2
- Batch-Kosten 52%
- Logische Lesevorgänge 4
- Körperlesungen 1
- Vorauslesen Liest: 8
- CPU-Zeit 0
- Abgelaufene Zeit 23ms
- Geschätzte Teilbaumkosten: 0.0054782
- CompileCPU: 0
- CompileMemory: 192
- CompileTime: 0
Persönlich ist Abfrage 1 effizienter, obwohl Abfrage 2 laut Grafikplan höhere Batch-Kosten verursacht. Dies liegt daran, dass Abfrage 2 weniger logische Lesevorgänge erfordert, die verstrichene Zeit etwas kürzer ist als die Werte für Compilecpu, Compilememory und Compiletime niedriger. Read-Ahead-Reads sind 8 für Abfrage 2 und 0 für Abfrage 1.
Update 12.03
Definition des Clustered Index
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
Nicht gruppierter Index 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