Ist die Reihenfolge der Spalten in einem PK-Index wichtig?
Ja tut es.
Standardmäßig wird die Primärschlüsseleinschränkung in SQL Server durch einen eindeutigen Clustered-Index erzwungen. Der Clustered-Index definiert die logische Reihenfolge der Zeilen in der Tabelle. Möglicherweise wird eine Reihe zusätzlicher Indexseiten hinzugefügt, um die oberen Ebenen des B-Tree-Index darzustellen. Die unterste (Blatt-) Ebene eines Clustered-Index ist jedoch einfach die logische Reihenfolge der Daten.
Um dies zu verdeutlichen, werden Zeilen auf einer Seite nicht unbedingt physisch in der Reihenfolge der gruppierten Indexschlüssel gespeichert. Es gibt eine separate Indirektionsstruktur innerhalb der Seite, die einen Zeiger auf jede Zeile speichert. Diese Struktur ist nach den gruppierten Indexschlüsseln sortiert. Außerdem hat jede Seite einen Zeiger auf die vorherige und nächste Seite auf derselben Ebene in der Reihenfolge der gruppierten Indexschlüssel.
Mit einem gruppierten Primärschlüssel von (RowNumber, DataDate)
werden die Zeilen zuerst nach RowNumber
und dann nach logisch sortiert DataDate
- also alle Zeilen, in denen sie RowNumber = 1
logisch gruppiert sind, dann Zeilen, in denen RowNumber = 2
usw.
Wenn Sie neue Daten (mit RowNumbers
1 bis n) hinzufügen , gehören die neuen Zeilen logischerweise zu den vorhandenen Seiten, sodass SQL Server wahrscheinlich viel Arbeit aufteilen muss, um Platz zu schaffen. All diese Aktivitäten verursachen eine Menge zusätzlicher Arbeit (einschließlich des Protokollierens der Änderungen) ohne Gewinn.
Geteilte Seiten beginnen ebenfalls zu 50% leer, sodass eine übermäßige Teilung auch zu einer geringen Seitendichte führen kann (weniger Zeilen als optimal pro Seite). Dies ist nicht nur eine schlechte Nachricht für das Lesen von Datenträgern (geringere Dichte = mehr zu lesende Seiten), die Seiten mit geringerer Dichte belegen auch mehr Speicherplatz im Cache.
Ändern des Clustered-Index in (DataDate, RowNumber
) ändern, werden neue Daten (die vermutlich höher sind DataDates
als die derzeit gespeicherten) auf neuen Seiten an das logische Ende des Clustered-Index angehängt. Dies beseitigt den unnötigen Overhead beim Teilen von Seiten und führt zu schnelleren Ladezeiten. Weniger fragmentierte Daten bedeuten auch, dass Vorausleseaktivitäten (Lesen von Seiten von der Festplatte, kurz bevor sie für eine laufende Abfrage benötigt werden) effizienter sind.
Wenn nichts anderes, suchen Ihre Abfragen viel häufiger nach DataDate
als RowNumber
. Ein Clustered-Index für (DataDate, RowNumber
unterstützt Index-Suchvorgänge für DataDate
(und dann RowNumber
). Die bestehende Anordnung unterstützt nur Suchvorgänge RowNumber
(und möglicherweise erst dann DataDate
). Möglicherweise können Sie den vorhandenen nicht gruppierten Index auf löschenDataDate
sobald der Primärschlüssel geändert wird. Der Clustered-Index ist breiter als der Nonclustered-Index, den er ersetzt. Sie sollten daher testen, um sicherzustellen, dass die Leistung akzeptabel bleibt.
Wenn Sie neue Daten mit importieren bcp
, erhalten Sie möglicherweise eine höhere Leistung, wenn die Daten in der Importdatei (idealerweise (DataDate, RowNumber
) nach den gruppierten Indexschlüsseln sortiert sind und Sie die folgende bcp
Option angeben :
-h "ORDER(DataDate,RowNumber), TABLOCK"
Um die beste Datenladeleistung zu erzielen, sollten Sie versuchen, minimal protokollierte Einfügungen zu erzielen. Weitere Informationen finden Sie unter:
Ja, die Reihenfolge ist kritisch. Ich bezweifle sehr, dass Sie jemals eine Anfrage nach RowNumber (zB
WHERE RowNumber=1
) stellen. Überwiegend werden Zeitreihen nach Datum (WHERE DataDate BEWEEN @start AND @end
) abgefragt, und solche Abfragen würden eine gruppierte Organisation nach erfordernDataDate
.Fragmentierung im Allgemeinen ist ein roter Hering. Die Reduzierung der Fragmentierung sollte hier nicht Ihr Ziel sein, aber eine ordnungsgemäße Organisation für Ihre Abfragen sollte es sein. Darüber hinaus ist es eine gute Idee, eine geringere Fragmentierung zu erreichen, aber kein eigenständiges Ziel. Wenn Sie über ein ordnungsgemäß organisiertes Datenmodell verfügen, das Ihrer Arbeitsauslastung entspricht (Ihre Abfragen werden ordnungsgemäß behandelt), und wenn Sie Messungen haben, die Fragmentierung als Auswirkung auf die Leistung anzeigen, können wir darüber sprechen.
quelle
WHERE
, in Abfragen häufig als Klausel gilt.