wie die Struktur eines index für group by in Sql Server
Die folgende einfache Abfrage dauert sehr lange (mehrere Minuten) zu führen.
Habe ich einen index:
create index IX on [fctWMAUA] (SourceSystemKey, AsAtDateKey)
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey in (1,2,3,4,5,6,7,8,9)
GROUP BY [t0].[SourceSystemKey]
Die Statistiken sind wie folgt:
- logische Lesevorgänge 1827978
- physische Lesevorgänge 1113
- read-aheads 1806459
Nehmen, dass genau die gleiche Abfrage und Formatierung wie folgt gibt mir diese Statistik:
- logische Lesevorgänge 36
- physische Lesevorgänge 0
- read-aheads 0
Es dauert 31ms zu führen.
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 1
GROUP BY [t0].[SourceSystemKey]
UNION
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 2
GROUP BY [t0].[SourceSystemKey]
UNION
SELECT MAX([t0].[AsAtDateKey]) AS [Date], [t0].[SourceSystemKey] AS [SourceSystem]
FROM [fctWMAUA] (NOLOCK) AS [t0]
WHERE SourceSystemKey = 3
GROUP BY [t0].[SourceSystemKey]
/* AND SO ON TO 9 */
Wie mache ich einen index hat, der die Gruppe durch schnell?
- Hast du einen index auf SourceSystemKey ? Wenn nicht, ich denke, Sie werden möglicherweise induziert einen full table scan.
- Was bedeutet die showplan-show? und welche Werte können SourceSystemKey nehmen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen, zu erklären, SQL Server verwenden den index:
Stellen Sie sicher, dass die Statistiken für die Tabelle werden bis zu Datum:
Für bessere Antworten, schalten Sie die showplan für beide Abfragen:
und fügen Sie die Ergebnisse zu Ihrer Frage.
Können Sie auch schreiben Sie die Abfrage ohne GROUP BY. Zum Beispiel können Sie eine exklusive LEFT JOIN ausschließen von Zeilen mit älteren Termin:
Dieser kann überraschend schnell, aber ich glaube nicht, dass es gegen die UNION.
Habe ich festgestellt, dass die beste Lösung ist die folgende.
Es ahmt die union version der Abfrage, und läuft sehr schnell.
40 logische Lesevorgänge und eine Ausführungszeit von 3ms.
Ist es schwer zu sagen, ohne Blick auf den Ausführungsplan, jedoch möchten Sie vielleicht versuchen, die folgenden:
Ist es schwer zu sagen, ohne Blick auf den Ausführungsplan, aber ich denke, dass was passiert ist, dass der SQL-server ist nicht klug genug, um zu begreifen, dass die WHERE-Klausel angegeben, ist die Filterung aus den Gruppen und haben keinen Einfluss auf die Datensätze enthalten für jede Gruppe. Sobald SQL server erkennt, dass seine frei, um etwas mehr inteligente index-lookups, um die maximalen Werte (das ist, was passiert in Ihrem zweiten Abfrage)
Nur eine Theorie, aber es könnte einen Versuch Wert sein.
Nutzen, die statt, WO, so dass die Filterung geschieht NACH der Gruppierung aufgetreten:
Ich auch nicht besonders Pflege für die IN-Klausel, vor allem, wenn es ersetzt werden könnte durch "<10" oder "Zwischen 1 und 9", die verwendet werden, besser sortiert Indizes.
Brauchen Sie nicht zu Gruppe, um einen festen Bereich.
Möglichkeit, die ich lieber den ersten Satz. Kann ich ersetzen die
etwas wie
oder
wenn SourceSystemKey ist eine ganze Zahl. Aber ich glaube nicht, dass es zu einer großen Veränderung.
Was ich zuerst testen, ist die Neuerstellung von Statistiken und erstellen Sie Indizes für die Tabelle und warten Sie einige Zeit. Umbau kommt nicht sofort, es wird davon abhängen, wie ausgelastet ist der server aber dieser Satz ist gut strukturiert, die für den index vom Optimierer verwendet werden.
Grüße.
Haben Sie versucht, erstellen Sie einen weiteren index nur auf die SourceSystemKey Spalte? Die hohe Anzahl logischer Lesevorgänge wenn man diese Spalte in der where-Klausel lässt mich denken, dass es eine index/table scan. Könnten Sie ausführen, wird der Ausführungsplan auf diese und sehen, ob das der Fall ist? Der Ausführungsplan kommen könnte mit einen index-Vorschlag als gut.