Die Frage lautet nicht "Wann sollte die PK NC sein?", Sondern "Was ist der richtige Schlüssel für den Clustered-Index?".
Und die Antwort hängt wirklich davon ab, wie Sie die Daten abfragen . Der Clustered-Index hat einen Vorteil gegenüber allen anderen Indizes: Da er immer alle Spalten enthält, ist er immer abdeckend. Daher müssen Abfragen, die den Clustered-Index nutzen können, keine Lookups verwenden, um einige der projizierten Spalten und / oder Prädikate zu erfüllen.
Ein weiteres Puzzleteil ist, wie ein Index verwendet werden kann . Es gibt drei typische Muster:
- Prüfpunkte, wenn ein einzelner Schlüsselwert im Index gesucht wird
- Bereichsscans, wenn ein Bereich von Schlüsselwerten abgerufen wird
- Auftrag nach Anforderungen, wenn ein Index einen Auftrag erfüllen kann, für den keine Stop-and-Go-Sortierung erforderlich ist
Wenn Sie also Ihre erwartete Auslastung (die Abfragen) analysieren und feststellen, dass eine große Anzahl von Abfragen einen bestimmten Index verwenden würde, weil sie ein bestimmtes Zugriffsmuster verwenden, das von einem Index profitiert, ist es sinnvoll, diesen Index als Clustered-Index vorzuschlagen.
Ein weiterer Faktor ist, dass der gruppierte Indexschlüssel der von allen nicht gruppierten Indizes verwendete Nachschlageschlüssel ist und daher ein breiter gruppierter Indexschlüssel einen Welligkeitseffekt erzeugt und alle nicht gruppierten Indizes verbreitert. Breite Indizes bedeuten mehr Seiten, mehr E / A , mehr Gedächtnis, weniger Güte.
Ein guter Clustered-Index ist stabil und ändert sich während der Lebensdauer der Entität nicht, da eine Änderung der Clustered-Index-Schlüsselwerte bedeutet, dass die Zeile gelöscht und wieder eingefügt werden muss.
Und ein guter Clustered-Index wächst nicht zufällig (jeder neu eingefügte Schlüsselwert ist größer als der vorhergehende), um Seitenteile und Fragmentierung zu vermeiden (ohne mit FILLFACTOR
s herumzuspielen ).
Nachdem wir nun wissen, was ein guter Clustered-Index-Schlüssel ist, entspricht der Primärschlüssel (eine logische Datenmodellierungseigenschaft) den Anforderungen? Wenn ja, sollte die PK geclustert werden. Wenn nein, sollte die PK nicht geclustert sein.
Betrachten Sie zum Beispiel eine Sales Facts-Tabelle. Jeder Eintrag hat eine ID, die der Primärschlüssel ist. Aber die überwiegende Mehrheit der Anfragen nach Daten zwischen einem Zeitpunkt stellen und einem anderen Termine, damit die besten gruppierten Indexschlüssel wären das Verkaufsdatum , nicht die ID . Ein weiteres Beispiel dafür, dass der Clustered-Index vom Primärschlüssel abweicht, ist ein Schlüssel mit sehr geringer Selektivität, wie z. B. eine Kategorie oder ein Status, ein Schlüssel mit nur sehr wenigen unterschiedlichen Werten. Ein gruppierter Indexschlüssel mit diesem Schlüssel mit geringer Selektivität als äußerster linker Schlüssel ist beispielsweise (state, id)
häufig sinnvoll, da bei Bereichsüberprüfungen nach allen Einträgen in einem bestimmten "Status" gesucht wird.
Ein letzter Hinweis zur Möglichkeit eines nicht gruppierten Primärschlüssels über einen Heap (dh es gibt überhaupt keinen gruppierten Index). Dies kann ein gültiges Szenario sein. Der typische Grund dafür ist, dass die Leistung von Masseneinfügungen kritisch ist, da Heaps im Vergleich zu Clustered-Indizes einen erheblich besseren Durchsatz von Masseneinfügungen aufweisen.
(state, id)
. In diesem Beispiel wird die Anforderung "Guter Clustered-Index wächst nicht zufällig" nicht erfüllt, nicht wahr? Können wir es also als guten Clustered-Index betrachten?Der Grund für die Verwendung von Clustered-Indizes ist in Wikipedia angegeben :
Angenommen, ich habe eine Tabelle mit Personen, und diese Personen haben eine Länderspalte und einen eindeutigen Primärschlüssel. Es ist eine demografische Tabelle, das sind also die einzigen Dinge, die mir wichtig sind. Welches Land und wie viele einzigartige Menschen sind an dieses Land gebunden.
Ich werde also immer nur WO AUSWÄHLEN oder NACH LÄNDERN BESTELLEN. Ein Clustered-Index für den Primärschlüssel hilft mir nicht weiter. Ich greife nicht über PK auf diese Daten zu, sondern über diese andere Spalte. Da eine Tabelle nur einen Clustered-Index enthalten kann, kann ich keinen Clustered-Index für ein Land verwenden, wenn ich meine PK als Clustered deklariere.
Außerdem finden Sie in diesem Artikel einen guten Überblick über Clustered- und Nonclustered-Indizes. In SQL Server 6.5 treten bei Clustered-Indizes Probleme mit der Einfügeleistung auf (was hoffentlich für die meisten von uns hier nicht relevant ist).
Beachten Sie, dass dies in späteren Versionen nicht der Fall ist.
quelle
Wenn es sich bei Ihrem Primärschlüssel
UNIQUEIDENTIFIER
um den handelt, müssen Sie diesen angebenNONCLUSTERED
. Wenn Sie es zu einem Cluster zusammenfassen, muss jede Einfügung eine Reihe von Datensätzen mischen, um die neue Zeile an der richtigen Position einzufügen. Dies wird die Leistung des Panzers verbessern.quelle
UNIQUEIDENTIFIER
Typ, der mit der gleichen Wahrscheinlichkeit eindeutige Schlüssel generiert, obwohl er immer noch eine Größe von 128 hat.Ein sehr verbreitetes Beispiel:
Customer
Tisch mitCustomerID
alsCLUSTERED PRIMARY KEY
OrderID (PK), CustomerID, OrderDate
und einigen anderen SpaltenOrderPositions
mitOrderPositionID (PK), OrderId, ProductID, Amount, Price ...
Natürlich ist "es kommt darauf an" - wie fast immer - die richtige Antwort, aber die meisten Anwendungen (nicht BI-Reports) funktionieren kundenbasiert (z. B. Sie melden sich als Kunde 278 auf der Website an und klicken auf "Meine Bestellungen" oder Der Sachbearbeiter listet alle Bestellungen für den Kunden 4569 auf, oder Ihre Rechnungsroutine summiert alle Bestellungen für den Kunden 137).
In diesem Fall wäre es nicht sinnvoll, die Tabelle nach dem zu gruppieren
OrderID
. Ja, Sie werden Fragen haben,SELECT ... WHERE OrderId = ?
um die Bestelldetails aufzulisten, aber dies wäre normalerweise eine kurze und billige Indexsuche (3 Lesevorgänge).Wenn Sie andererseits Ihre
Order
Tabelle nach dem gruppieren würdenCustomerID
, müssten Sie nicht jedes Mal mehrere Schlüsselsuchen durchführen , wenn Sie die Tabelle abfragenCustomerId = ?
.Das
CLUSTERED INDEX
sollte immer so seinUNIQUE
, sonst würde SQL Server eine unsichtbare (= nicht verwendbare) INT-Spalte hinzufügenUNIQUIFIER
, um die Eindeutigkeit sicherzustellen - und es wäre viel sinnvoller, echte (verwendbare) Daten hinzuzufügen, als zufällige (abhängig von der Einfügereihenfolge) Daten.Da ein Kunde (hoffentlich) mehr als eine Bestellung aufgeben wird , müssten wir entweder die
OrderID
oder (falls Sie dies normalerweise sortieren) dieOrderDate
(falls es sich um eine Datumszeit handelt - ansonsten wäre der Kunde auf eine Bestellung pro Tag beschränkt) hinzufügen dasCLUSTERED INDEX
und am Ende mit:CREATE UNIQUE CLUSTERED INDEX IX_Orders_UQ on Orders (CustomerID, OrderID)
Die gleichen Regeln gelten für die
OrderPositions
Tabelle. In der Regel werden in den meisten Abfragen alle Positionen für eine bestimmte Reihenfolge aufgelistet. Daher sollten Sie die PK mit dem BuchstabenOrderPositionID
asNONCLUSTERED
und aUNIQUE CLUSTERED INDEX
on erstellenOrderId, OrderPositionID
.Übrigens: Es ist richtig, dass die
Customer
Tabelle von ihrer PK geclustert wird (CustomerID
da es sich um eine "Top-Level-Tabelle" handelt) und in einer typischen Anwendung meistens von ihrer CustomerID abgefragt wird.Reine Lookup - Tabellen , wie zB
Genders
oderInvoiceTypes
oderPaymentType
sind ein weiteres Beispiel für Tabellen , die durch seine PK geclustert werden sollen (weil Sie in der Regel kommen sie aufGenderId
,InvoiceTypeId
oderPaymentTypeId
).quelle
Wenn ein Clustered-Index für das Gesamtsystem vorteilhafter ist als eine Clustered-PK, indem ein Leistungsmaß verwendet wird. Es kann nur einen Clustered-Index für eine Tabelle geben.
Beispielhafte Leistungsindikatoren sind die einzelne Abfragezeit (Geschwindigkeit), die Integration der gesamten Abfragezeiten für die Tabelle (Effizienz) und das Hinzufügen vieler Include-Spalten zu einem sehr großen, nicht gruppierten Index, um eine Leistung zu erzielen, die der gruppierten (Größe) ähnelt ).
Dies kann vorkommen, wenn Daten im Allgemeinen mit einem Index abgerufen werden, der nicht eindeutig ist, Nullen enthält (in einer PK nicht zulässig) oder die PK aus einem sekundären Grund hinzugefügt wurde (z. B. Replikation oder Identifizierung von Audit-Trail-Datensätzen).
quelle