Beide Tabellen haben dieselbe Struktur und 19972 Zeilen in jeder Tabelle. Zum Üben der Indizierung habe ich beide Tabellen mit der gleichen Struktur erstellt und erstellt
clustered index on persontb(BusinessEntityID)
und
nonclustered index on Persontb_NC(BusinessEntityId)
und Tabellenstruktur
BusinessEntityID int
FirstName varchar(100)
LastName varchar(100)
-- Nonclusted key on businessentityid takes 38%
SELECT BusinessEntityId from Persontb_NC
WHERE businessentityid BETWEEN 400 AND 4000
-- CLustered key businessentityid takes 62%
SELECT BusinessEntityId from persontb
WHERE businessentityid BETWEEN 400 AND 4000
Warum nimmt der Clustered-Index 62% und der Nicht-Clustered-Index 38% ein?
Antworten:
Ja, der Clustered-Index enthält weniger Zeilen pro Seite als der Nicht-Clustered-Index, da die Blattseiten des Clustered-Index die Werte für die beiden anderen Spalten (
FirstName
undLastName
) speichern müssen .Die Blattseiten des NCI speichern nur die
BusinessEntityId
Werte und einen Zeilenlokator (RID, wenn die Tabelle ein Heap oder der CI-Schlüssel ist).Die geschätzten Kosten spiegeln also die größere Anzahl von Lesevorgängen und den E / A-Bedarf wider.
Wenn Sie das NCI als deklarieren würden
dann wäre es ähnlich wie der Clustered-Index.
quelle
Der Clustered-Index enthält nicht nur Daten aus dem aktivierten Spaltenindex, sondern auch Daten aus allen anderen Spalten. (Es kann nur einen Clustered-Index pro Tabelle geben.)
Der nicht gruppierte Index enthält nur Daten aus indizierten Spalten und einen row_id-Zeiger darauf, wo sich der Rest der Daten befindet.
Daher ist dieser bestimmte nicht gruppierte Index leichter und es ist weniger Lesen erforderlich, um ihn zu scannen / zu durchsuchen, und diese bestimmte Abfrage funktioniert schneller.
Wenn Sie jedoch versucht haben, auch Vorname und Nachname abzurufen, ist dies unterschiedlich und der Clustered-Index sollte eine bessere Leistung erzielen.
quelle
Die Prozentsätze zwischen den Abfrageplänen sind für einen direkten Vergleich bedeutungslos. Sie müssen die Abfragen vergleichen, um einen gültigen Vergleich zu erhalten. Darüber hinaus neigen kleine Zeilenzahlen dazu, Leistungsunterschiede zwischen Indizierungsstrategien zu verbergen. Wenn Sie die Anzahl der Zeilen auf 10 Millionen erhöhen, erhalten Sie ein klareres Bild der Leistungsunterschiede.
Es gibt ein Beispielskript, das drei Tabellen erstellt, Ihre beiden von oben, und eine dritte mit einem gruppierten und einem nicht gruppierten Index.
Füllen Sie die Tabellen mit 10 Millionen Zeilen
Wir können sys.dm_db_index_physical_stats verwenden, um die Größe der Indizes auf der Festplatte anzuzeigen.
Und die Ergebnisse:
Der Clustered-Index von T1 ist ungefähr 1,6 GB groß. Der nicht gruppierte Index von T2 beträgt 170 MB (90% Einsparung an E / A). Der nicht gruppierte Index von T3 beträgt 97 MB oder etwa 95% weniger E / A als T1.
Basierend auf den erforderlichen E / A-Vorgaben sollte der ursprüngliche Abfrageplan eher 10% / 90% und nicht 38% / 62% betragen. Da der nicht gruppierte Index wahrscheinlich vollständig in den Speicher passt, kann der Unterschied noch größer sein, da die Festplatten-E / A sehr teuer ist.
quelle
10%/90%
Zahl genauer ist als die38%/62%
. Zeichenfolgen mit einer Länge zwischen 100 und 200 sind sicherlich eine grobe Überschätzung des Speicherplatzbedarfs für ein Paar aus Vorname und Nachname, sodass Sie eine geringere Seitendichte als das OP haben. Wenn ich es mit Ihren Beispieldaten versuche, werden die geschätzten Kosten mit 87% / 13% angezeigt .data_pages
insys.allocation_units
. Sie können dies sehen,CREATE TABLE T1(C INT);CREATE TABLE T2(C INT);UPDATE STATISTICS T1 WITH PAGECOUNT = 1;UPDATE STATISTICS T2 WITH PAGECOUNT = 100
wenn Sie dann die geschätzten Kosten vergleichenSELECT * FROM T1;SELECT * FROM T2;