Ich habe nur ein paar Monate in SQL Server programmiert, daher sind meine Kenntnisse in vielerlei Hinsicht nicht gut. In einem bereits vorhandenen Projekt stieß ich auf viele Tabellen mit großen zusammengesetzten Primärschlüsseln mit Clustered-Index. Nach dem, was ich zusammengetragen habe, beeinträchtigt eine große Spalte / zusammengesetzte Spalte mit gruppiertem Index die Leistung sehr stark, und manchmal ist die logische Lösung eine Identitätsspalte. Gleichzeitig bin ich auf viele Menschen gestoßen, die die übermäßige Verwendung von Identitätsspalten in Flammen gesetzt haben.
Aber ich bin noch nie auf ein Beispiel gestoßen, bei dem eine Identitätsspalte eine schlechte Idee ist.
Kürzlich haben wir standardisiert, dass jede Tabelle eine Identitätsspalte als Clustered-Index haben soll - unabhängig davon, ob wir sie als PK verwenden oder nicht, da wir sie für einige Exportzwecke benötigen.
Daher möchte ich einige Beispiele in realen Szenarien, in denen die Verwendung einer Identitätsspalte als Clustered-Index eine schlechte Idee ist.
Obwohl es manchmal unser Leben leichter macht, bin ich nie auf ein Szenario gestoßen, in dem es als schlecht angesehen wird.
PS: Ich denke, meine Frage ist ein bisschen naiv, aber sie nervt mich so sehr, dass ich danach fragen musste.
INT IDENTITY
als Primärschlüssel (und Clustered-Schlüssel) für fast jede Tabelle zu verwenden. Es ist eine empfehlenswerte Best Practice und funktioniert normalerweise einwandfrei. Fälle, in denen dies keine gute Idee ist, sind meiner Meinung nach relativ selten.Antworten:
Normalerweise verwende ich eine Identitätsspalte als gruppierten Primärschlüssel. In einigen (seltenen?) Fällen ist dies jedoch aufgrund der LastPageInsertLatchContention nicht ideal. Dies geschieht, wenn eine Tabelle stark mit Daten gefüllt ist. Aufgrund des Identitätsschlüssels möchten alle diese INSERT's die letzte Seite der Tabelle (Index) schreiben. Diese Seite kann also gesperrt werden und die Leistung kann mit einer anderen Lösung besser sein.
Sehen
http://dangerousdba.blogspot.ch/2011/10/bit-reversion.html
http://blogs.msdn.com/b/sqlserverfaq/archive/2010/05/27/monotonisch-erhöhend-clustered-index-keys-can-cause-latch-contention.aspx
für Details.
quelle
Ich habe nie eine Identitätsspalte gesehen, die nicht auch ein Index ist, normalerweise der Primärschlüssel.
Jetzt müssen wir zwischen Primärschlüssel (PK) und Clustered Index (CI) unterscheiden. Der erste dreht sich um die Logik des Datenbankschemas, der Primärschlüssel unterscheidet eine Zeile von allen anderen in der Tabelle und der Fremdschlüssel für andere Tabellen. Eine Identitätsspalte ist immer ein Kandidatenschlüssel, aber sie ist künstlich und Sie möchten möglicherweise den natürlichen Kandidatenschlüssel als PK.
Beim Clustered Index geht es stattdessen darum, wie der Index aus den Daten erstellt und gespeichert wird. Es kann nur einen Clustered-Index geben, und dies ist der einzige Index, der auf die Daten in der Tabelle verweist. Alle anderen Indizes beziehen sich auf den Clustered-Index.
Normalerweise ist die PK auch das CI, aber das ist einfach das Standardverhalten. Ich habe PK gesehen und manchmal erstellt, die kein CI waren: Der PK war der natürliche Schlüssel, der CI war die Identitätsspalte. Um die Funktionsweise des Index zu vereinfachen, ist der Index umso schneller, je kleiner die Daten in der CI-Definition sind, und das CI muss so schnell wie möglich sein. In Fällen, in denen die PK sehr groß ist und eine Identitätsspalte wie die hat Wenn Sie den Clustered-Index und die PK zu einem Nicht-Clustering-Index machen, wird die Leistung verbessert.
Meiner Meinung nach ist die Verwendung einer Identitätsspalte als Clustered-Index keine schlechte Idee, aber das bedeutet nicht, dass sie auch der Primärschlüssel sein sollte.
Das einzige Szenario, in dem ich mir vorstellen kann, dass eine Identitätsspalte eine schlechte Wahl sein kann, ist, wenn so viele eingehende Daten vorhanden sind, dass selbst die Erstellung der Identität die Leistung beeinträchtigt.
quelle
Welche Schlüssel / Indizes zu gruppieren sind, ist keine exakte Wissenschaft. Die beste Verwendung eines Clustered-Index kann je nach Verwendung der Tabelle (und der Verwendung der Spalten in diesem Schlüssel) variieren.
Der Clustered Key ist effizienter für Abfragen, bei denen viele Zeilen in einem Bereich ausgewählt werden, da keine zusätzlichen Zeilensuchen erforderlich sind, um die Daten für die nach dem Durchsuchen des Index gefundenen Zeilen zu finden. Es hilft auch bei der Suche nach einzelnen Zeilen, aber der Unterschied ist nicht so deutlich. Zum Beispiel haben wir Tabellen, die häufig nach der Objektbesitzer-ID durchsucht werden (und nicht nach der Objekt-ID, die der Primärschlüssel ist). Daher ist es für unsere App effizienter, wenn der Index für diese Spalte der Cluster-Schlüssel ist, ähnlich wie es manchmal der Fall ist Es ist viel besser, den Clusterschlüssel in häufig referenzierten Datumsspalten zu haben, wenn häufig nach Zeilen über Datumsbereichen gesucht wird.
Wenn die PK einer bestimmten Tabelle häufig ein Verknüpfungsziel ist, kann das Clustering der PK hilfreich sein, da bei bestimmten Verknüpfungsvorgängen die Reduzierung weiterer Seitensuchen ein großer Bonus sein kann, und natürlich, wenn Sie eine PK haben, die auf realen Daten basiert (und nicht) Ein Ersatzschlüssel wie eine Auto-Inkrement-Nummer (UUID), der Fernabfragen unterliegt, bietet die erwarteten Vorteile. Diese Gründe sind der Grund, warum das Clustering Ihrer PK im Allgemeinen eine gute Ausgangsposition ist, bevor andere Überlegungen berücksichtigt werden, und daher eine häufige Empfehlung (und manchmal eine automatisch angewendete Standardeinstellung).
Als Randnotiz: Wenn Sie am Ende eine UUID-Spalte anstelle eines inkrementierenden Integer-Typs als PK in einer Tabelle verwenden, kann das Clustering darauf die Leistung beeinträchtigen, da die zusätzlichen Seitenaufteilungen durch Einfügen "zufälliger" Daten in den Index ( Jede im Clustered-Index geteilte Seite führt zu einer zusätzlichen E / A-Aktivität auch für alle anderen Indizes in der Tabelle. Dies verlangsamt Einfügungen und kann Fragmentierungsprobleme im Laufe der Zeit verschlimmern. In dieser Situation kann es daher oft viel besser sein, einen anderen Index zu gruppieren (oder manchmal überhaupt keinen Clustered-Index zu haben
, obwohl dies unter SQL Server für Azure[1]nicht möglich istund es selten vorkommt, dass kein Clustered-Schlüssel vorhanden ist insgesamt eher ein Vorteil als ein Nachteil).[1] Es ist seit einiger Zeit möglich, einen Heap (eine Tabelle ohne Clustering-Schlüssel) in Azure SQL zu haben, obwohl ähnliche Einschränkungen wie in On-Pre-SQL Server selten eine gute Idee sind
quelle
Im Allgemeinen ist es eine schlechte Idee, wenn der Identitätsclusterindex einfach ein redundanter, zusätzlicher Index ist. Sie erhalten nur einen Clustered-Index. Wenn Sie also den falschen auswählen, werden alle Ihre Transaktionen kostenpflichtig.
Wenn Sie bereits einen zusammengesetzten Schlüssel oder einen natürlichen Schlüssel benötigen, ist es eine schlechte Idee, eine Identitätsspalte als Clustered-Index zu haben.
Zwei gängige Szenarien, in denen zusammengesetzte Schlüssel verwendet werden sollten, sind "Tabellen verknüpfen" und "verschachtelte Tabellen", z.
Das Hinzufügen eines Identitätsspalten-Clustered-Index ist nutzlos und schädlich.
Ein häufiges Beispiel für die zweite Tabelle sind "verschachtelte" Tabellen, bei denen nur eine einzige zusammengesetzte PK erforderlich ist:
Unumstrittene Anwendungsfälle für natürliche Schlüssel umfassen Nachschlagetabellen, z
Etwas kontroverser, aber IMO-korrekt ist die Verwendung von sequentiellem UNIQUEIDENTIFIER als Cluster-PK. Dies ist auch ein Szenario, in dem das Hinzufügen einer IDENTITY-Spalte mit einem Clustered-Index schädlich ist.
quelle
Wenn Sie Detailtabellen implementieren und einen einspaltigen Primärschlüssel beibehalten möchten, sollten Sie Folgendes berücksichtigen:
Ich habe die übergeordnete Tabelle mit einem gruppierten Primärschlüssel in der Identitätsspalte eingerichtet. Für die Parent_Detail-Tabelle ist die Identitätsspalte der Primärschlüssel, der Clustering-Index befindet sich jedoch auf dem Fremdschlüssel (Parent_ID), gefolgt von der Identitätsspalte. Indem wir die Identitätsspalte zum Clustering-Index hinzufügen (wie es David Browne in seiner Lösung getan hat) und dann den Clustering-Index als eindeutig definieren, vermeiden wir den 4-Byte-Eindeutiger. Obwohl der Uniquifier nur hinzugefügt wird, wenn dies für bestimmte Datensätze erforderlich ist ( https://sqlquantumleap.com/2017/09/18/clustered-index-uniquifier-existence-and-size/ hat eine gute Beschreibung), fühle ich mich besser Definieren meiner Cluster-Indizes für Nicht-Primärschlüssel mit UNIQUE, wenn möglich.
Durch Clustering mit der Spalte Parent_ID an der führenden Position aktivieren wir den Clustered-Index-Range-Scan zum Identifizieren von Detaildatensätzen für einen bestimmten übergeordneten Datensatz, wodurch die Leistung für diesen allgemeinen Anwendungsfall verbessert werden sollte.
quelle