Bei einer Tabelle mit einem Primärschlüssel, z.
CREATE TABLE Customers (
CustomerID int NOT NULL PRIMARY KEY,
FirstName nvarchar(50),
LastName nvarchar(50),
Address nvarchar(200),
Email nvarchar(260)
--...
)
Wir haben einen eindeutigen Primärschlüssel an CustomerID
.
Traditionell benötige ich dann möglicherweise einige zusätzliche Deckungsindizes. Zum Beispiel, um schnell einen Benutzer zu finden, indem Sie entweder CustomerID
oder Email
:
CREATE INDEX IX_Customers_CustomerIDEmail ON Customers
(
CustomerID,
Email
)
Und das sind die Arten von Indizes, die ich seit Jahrzehnten erstellt habe.
Es muss nicht eindeutig sein, ist es aber tatsächlich
Der Index selbst ist vorhanden, um einen Tabellenscan zu vermeiden. Es handelt sich um einen Deckungsindex, um die Leistung zu verbessern (der Index dient nicht als Einschränkung für die Durchsetzung der Eindeutigkeit).
Heute habe ich mich an ein paar Informationen erinnert - SQL Server kann die Tatsache nutzen, dass:
- Eine Spalte hat eine Fremdschlüsseleinschränkung
- Eine Spalte hat einen eindeutigen Index
- Eine Einschränkung ist vertrauenswürdig
um die Abfrageausführung zu optimieren. In der Tat aus dem SQL Server Index Design Guide :
Wenn die Daten eindeutig sind und die Eindeutigkeit erzwungen werden soll, bietet das Erstellen eines eindeutigen Index anstelle eines nicht eindeutigen Index für dieselbe Spaltenkombination zusätzliche Informationen für das Abfrageoptimierungsprogramm, mit denen effizientere Ausführungspläne erstellt werden können . In diesem Fall wird empfohlen, einen eindeutigen Index zu erstellen (vorzugsweise durch Erstellen einer EINZIGARTIGEN Einschränkung).
Da mein mehrspaltiger Index den Primärschlüssel enthält , ist dieser zusammengesetzte Index de facto eindeutig. Es ist keine Einschränkung, die SQL Server bei jeder Einfügung oder Aktualisierung besonders erzwingen muss. aber die Tatsache ist , dass dieser Nicht-Clustered - Index ist einzigartig.
Gibt es einen Vorteil, diesen de facto eindeutigen Index als tatsächlich eindeutig zu kennzeichnen?
CREATE UNIQUE INDEX IX_Customers_CustomerIDEmail ON Kunden ( Kundennummer, Email )
Es scheint mir, dass SQL Server intelligent genug sein könnte , um zu erkennen, dass mein Index bereits eindeutig ist , da er den Primärschlüssel enthält.
- Aber vielleicht weiß es das nicht und es gibt einen Vorteil für den Optimierer, wenn ich den Index trotzdem als eindeutig deklariere.
- Außer vielleicht könnte dies jetzt zu Verlangsamungen bei Einfügungen und Aktualisierungen führen, bei denen Eindeutigkeitsprüfungen durchgeführt werden müssen - wo zuvor noch nie zuvor.
- Es sei denn, es weiß, dass der Index garantiert bereits eindeutig ist, da er den Primärschlüssel enthält.
Ich kann keine Anleitung von Microsoft finden, was zu tun ist, wenn ein zusammengesetzter Index den Primärschlüssel enthält.
Zu den Vorteilen eindeutiger Indizes gehören:
- Die Datenintegrität der definierten Spalten ist gewährleistet.
- Zusätzliche Informationen, die für das Abfrageoptimierungsprogramm hilfreich sind, werden bereitgestellt.
Sollte ich einen zusammengesetzten Index als eindeutig markieren, wenn er bereits den Primärschlüssel enthält? Oder kann SQL Server dies selbst herausfinden?
quelle
Antworten:
Wahrscheinlich nicht. Das Optimierungsprogramm kann im Allgemeinen ohnehin Informationen über die Eindeutigkeit der enthaltenen Schlüsselspalte verwenden, sodass es keinen wirklichen Vorteil gibt.
Es gibt auch eine wichtige Konsequenz , wenn ein Index in Aktualisierungsplänen, die die Schlüssel dieses Index ändern, eindeutig ist, um Folgendes zu berücksichtigen:
Installieren
Aktualisierungsplan pro Index (nicht eindeutiger Index)
Ausführungsplan:
Der Optimierer trifft häufig eine kostenbasierte Entscheidung zwischen der Aktualisierung nicht gruppierter Indizes pro Zeile (ein "enger" Plan) oder pro Index (ein "breiter" Plan). Die Standardstrategie (mit Ausnahme von speicherinternen OLTP-Tabellen) ist ein umfassender Plan.
Enge Pläne (bei denen nicht gruppierte Indizes gleichzeitig mit dem Heap- / Clustered-Index verwaltet werden) sind eine Leistungsoptimierung für kleine Aktualisierungen. Diese Optimierung ist nicht in allen Fällen implementiert. Die Verwendung bestimmter Funktionen (z. B. indizierter Ansichten) bedeutet, dass die zugehörigen Indizes in einem umfassenden Plan verwaltet werden.
Weitere Informationen: Optimieren von T-SQL-Abfragen, die Daten ändern
In diesem Fall habe ich das undokumentierte Ablaufverfolgungsflag 8790 verwendet, um einen umfassenden Aktualisierungsplan zu erzwingen: Der Plan zeigt daher, dass die gruppierten und nicht gruppierten Indizes getrennt verwaltet werden.
Der Split verwandelt jedes Update in ein separates Lösch- und Einfügepaar. Der Filter filtert alle Zeilen heraus, die nicht zu einer Änderung des Index führen würden.
Weitere Informationen: ( Nicht aktualisierte Updates ) vom SQL Server QO-Team.
Aktualisierungsplan pro Index (eindeutiger Index)
Ausführungsplan:
Beachten Sie die zusätzlichen Sortier- und Reduzierungsoperatoren, wenn der Index als eindeutig markiert ist.
Dieses Split-Sort-Collapse-Muster ist erforderlich, wenn die Schlüssel eines eindeutigen Index aktualisiert werden, um Verstöße gegen eindeutige Schlüssel zwischenzeitlich zu verhindern.
Weitere Informationen: Pflege eindeutiger Indizes von Craig Freedman
Insbesondere die Sortierung kann ein Problem sein. Dies ist nicht nur ein unnötiger Mehraufwand, sondern kann auch auf die Festplatte übertragen werden, wenn die Schätzungen ungenau sind.
Über nicht gruppierte Schlüssel
Ein weiterer zu berücksichtigender Faktor ist, dass nicht gruppierte Indexstrukturen auf jeder Indexebene immer eindeutig sind, auch wenn sie
UNIQUE
nicht angegeben sind. Die Cluster-Schlüssel - und möglicherweise ein Eindeutiger, wenn der Cluster-Index nicht als eindeutig markiert ist - werden auf allen Ebenen einem nicht eindeutigen, nicht gruppierten Index hinzugefügt.Infolgedessen die folgende Indexdefinition:
... enthält tatsächlich die Schlüssel (E-Mail, Kunden-ID) auf allen Ebenen. Es ist daher in beiden Spalten "suchbar":
Weitere Informationen: Weitere Informationen zu nicht gruppierten Indexschlüsseln von Kalen Delaney
quelle
SQL weiß, dass es bereits eindeutig ist (wenn es die PK enthält, kann es nicht eindeutiger werden), unabhängig davon, ob Sie es explizit angeben.
Der große Unterschied zwischen einem nicht eindeutigen Index und einem eindeutigen Index besteht darin, dass für nicht eindeutige Indizes der Clustered-Indexschlüssel (mit dem eindeutigen Wert, wenn der CIX nicht als eindeutig deklariert ist) auf den höheren Ebenen des Index erforderlich ist, nicht nur am Blatt Niveau.
In Ihrem Fall haben Sie den CIX bereits im Schlüssel, was bedeutet, dass er sich bereits auf jeder Ebene des Index befindet.
Sie können jedoch eine Tabelle erstellen, die eine separate PK (eindeutig) und CIX (egal) enthält. Erstellen Sie dann einen nicht eindeutigen Index, der die PK in ihrem Schlüssel enthält. Fügen Sie einige Zeilen in die Tabelle ein, einschließlich einiger leicht auffindbarer Varchar-Werte für Ihre CIX-Spalte. Fügen Sie genügend Zeilen ein, um mehrere Ebenen Ihrer Indizes zu erstellen. Dann können Sie DBCC IND verwenden, um die Seiten in Ihrem NCIX zu finden, und DBCC PAGE, um einige zu öffnen, um die Daten zu überprüfen und festzustellen, ob die CIX-Schlüsselwerte auf den höheren Ebenen liegen.
quelle