Ich verbinde eine kleine Tabelle (1.000 Zeilen) mit einer großen Tabelle (8 Millionen Zeilen) in SQL Server 2008. Der Join verwendet einen nicht gruppierten Abdeckungsindex für die große Tabelle, und der Join kann drei mögliche Abfragepläne erstellen. Ich versuche herauszufinden, welcher Plan besser ist, aber ich möchte dieses Wissen auch verallgemeinern, damit ich beim nächsten Mal besser wissen kann, welche Heuristiken beim Betrachten von SQL-E / A-Statistiken verwendet werden sollen.
Plan Nr. 1 ist ein Loop-Join und gibt Statistiken für die große Tabelle wie folgt aus:
Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052
Plan 2 ist ein Zusammenführungs-Join und gibt Statistiken wie folgt aus:
Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004
Plan Nr. 3 ist ein Hash-Join und gibt Statistiken wie folgt aus:
Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010
Der Deckungsindex ist geordnet nach (ID, Date)
. Die Abfrage gibt Daten für ungefähr 50% der IDs zurück und gibt für jede ID einen zusammenhängenden Teil der Daten der letzten 3 Monate zurück, der normalerweise ungefähr 1/4 oder die Zeilen für jede ID beträgt. Die Abfrage gibt ungefähr 1/8 der gesamten Zeilen im Index zurück. Mit anderen Worten, die Abfrage ist spärlich, aber konsistent.
Ich gehe davon aus, dass Plan Nr. 1 für diese Arbeitslast schrecklich ist, da das Bewegen des Plattenkopfs um das 2.500-fache (oder sogar 1.041-fache) weitaus teurer ist als ein sequentieller Platten-Scan. Ich gehe auch davon aus, dass # 3 und # 2 ähnliche, sequentielle (und daher effizientere) E / A-Muster haben.
Aber gibt es einen Fall, in dem Plan 1 wirklich am besten ist, in dem "am besten" weniger Auswirkungen auf das E / A-Subsystem und weniger Auswirkungen auf andere gleichzeitig ausgeführte Abfragen bedeutet?
Oder hängt es wirklich von vielen Variablen ab, wie der Art meines Festplattensubsystems, der Indexfragmentierung usw. Wenn "es davon abhängt", gibt es Faustregeln, um das Problem anzugehen?