Dieser Abschnitt enthält die SQL Server Skripts und Ausführungspläne für Kapitel 6, „Sortieren und Gruppieren“.
Indexed Order By
DROP INDEX sales_date ON sales;
GO
CREATE INDEX sales_dt_pr ON sales (sale_date, product_id);
GO
EXEC sp_updatestats;
GO
SET STATISTICS PROFILE ON;
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date = DATEADD(day, -1, GETDATE())
ORDER BY sale_date, product_id;
Für die order by
-Klausel wird keine explizite Sortierung durchgeführt:
Nested Loops(Inner Join, OUTER REFERENCES:[Bmk1000])
|--Index Seek(OBJECT:([sales].[sales_dt_pr]),
| SEEK:[sales].[sale_date]=dateadd(day,(-1),getdate())
| ORDERED FORWARD)
|--RID Lookup(OBJECT:([sales]),
SEEK:[Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD
Derselbe Ausführungsplan wird benutzt, wenn nur nach PRODUCT_ID
gruppiert wird:
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date = DATEADD(day, -1, GETDATE())
ORDER BY product_id;
Die Benutzung des Größer-Gleich Operators erzwingt eine Sortierung:
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
ORDER BY product_id;
Sort(ORDER BY:([test].[dbo].[sales].[product_id] ASC))
|--Nested Loops(Inner Join, OPTIMIZED WITH UNORDERED PREFETCH)
|--Compute Scalar(DEFINE:([Expr1009]=BmkToPage([Bmk1000])))
| |--Nested Loops(Inner Join)
| |--Compute Scalar([...])
| | |--Constant Scan
| |--Index Seek(OBJECT:([sales].[sales_dt_pr]),
| SEEK:([sales].[sale_date] > [Expr1007]
| AND [sales].[sale_date] < NULL) ORDERED FORWARD)
|--RID Lookup(OBJECT:([sales]),
SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
Indexed ASC/DESC und NULLS FIRST/LAST
Der Index kann auch rückwärts benutzt werden:
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
ORDER BY sale_date DESC, product_id DESC;
Gemischtes ASC
/DESC
erzwingt wieder eine Sortierung:
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
ORDER BY sale_date ASC, product_id DESC;
ASC
/DESC
kann aber auch indiziert werden, damit die Sortierung wieder entfallen kann:
DROP INDEX sales_dt_pr ON sales;
GO
CREATE INDEX sales_dt_pr
ON sales (sale_date ASC, product_id DESC);
GO
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
ORDER BY sale_date ASC, product_id DESC;
SQL Server 2008R2 setzt die NULLS
Erweiterung nicht um:
SELECT sale_date, product_id, quantity
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
ORDER BY sale_date ASC, product_id DESC NULLS LAST;
Indexed Group By
Pipelined group by
Ausführung:
SELECT product_id, SUM(eur_value)
FROM sales
WHERE sale_date = DATEADD(day, -1, GETDATE())
GROUP BY product_id;
SQL Server verwendet ein explizites Sort/Group wenn zwei Tage gelesen werden (Parallelisierung zur besseren Lesbarkeit abgeschalten).
SELECT product_id, SUM(eur_value)
FROM sales
WHERE sale_date >= DATEADD(day, -1, GETDATE())
GROUP BY product_id
OPTION (MAXDOP 1);
Wenn man einen größeren Zeitraum wählt, wird der Hash-Algorithmus benutzt:
SELECT product_id, SUM(eur_value)
FROM sales
WHERE sale_date >= DATEADD(day, -100, GETDATE())
GROUP BY product_id
OPTION (MAXDOP 1);