Wir haben einen großen Tisch , [MyTable]
die derzeit sowohl eine hat Primary Key
, und eine Unique Non Clustered Index
auf der gleichen Spalte ( [KeyColumn]
). Der U NC-Index enthält außerdem zusätzliche Deckspalten.
Es scheint überflüssig, sowohl PK als auch Unique NC Index in denselben Spalten zu haben. Daher habe ich überlegt, den Primärschlüssel zu löschen und stattdessen den Unique Non Clustered Index für Zwecke der referenziellen Integrität zu verwenden.
Beachten Sie, dass die Tabelle vollständig von einer anderen Spalte geclustert wird.
Also haben wir:
ALTER TABLE [MyTable]
ADD CONSTRAINT [PK_MyTable]
PRIMARY KEY NONCLUSTERED ([KeyColumn])
GO
UND
CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex]
ON [MyTable] ([KeyColumn])
INCLUDE ([Column1], [Column2])
GO
Soweit mir bekannt ist, ist es nicht möglich, einem Primärschlüssel überdeckende Spalten hinzuzufügen. Daher beabsichtige ich Folgendes:
- Löschen Sie die Fremdschlüsseleinschränkungen, auf die Sie angewiesen sind
MyTable.KeyColumn
- Legen Sie den Primärschlüssel
MyTable.KeyColumn
vollständig auf - Fügen Sie die Fremdschlüssel erneut zur Tabelle hinzu (dh RI wird erzwungen über
MyTable.KeyColumn
).
Die einzige Implikation, die ich mir dabei vorstellen kann, ist, dass wir in unseren ERD-Diagrammen kein visuelles Schlüsselsymbol erhalten und dass die (Blatt-) Indexdichte aufgrund der enthaltenen Spalten geringer sein wird.
Ich habe /programming/487314/primary-key-or-unique-index gelesen und bin mit den Integritäts- und Leistungsaspekten dabei zufrieden.
Meine Frage ist: Ist dieser Ansatz fehlerhaft?
Bearbeiten Sie, was ich erreichen möchte : Leistungsoptimierung und Frühjahrsputz . Wenn Sie entweder den PK oder einen Index entfernen, werden weniger Seiten für meine Indizes benötigt = schnellere Schreibvorgänge, plus auch Wartungs- / Betriebsvorteile, dh ein Index weniger, um defragmentiert zu bleiben usw.
Um dies etwas näher zu erläutern: Ich hatte noch nie zuvor eine Tabelle, auf die verwiesen wird, ohne eine PK. Die Tatsache, dass der Tabelle ein NC-Index mit abdeckenden Spalten hinzugefügt wurde, bedeutet jedoch, dass ich mein Denken anpassen muss.
quelle
Antworten:
Sie müssen nachweisen können, dass das, was vorgeschlagen wird, tatsächlich hilft (Kosten-Nutzen-Verhältnis). Aus welchem Grund wird diese Änderung in Betracht gezogen? Gibt es tatsächlich Leistungsprobleme mit dieser Tabelle, oder sah es einfach "falsch aus"?
Hier sind einige andere Fragen, die Ihnen helfen, die beste Entscheidung für Ihre Umgebung zu treffen:
Wie viel Zeit würde im Wartungsfenster gespart? Im Backup-Fenster?
Wie viel Speicherplatz würde dies einsparen (Datendateien, Protokolldateien, Sicherungen usw.)?
Ist die
INSERT
Leistung an diesem Tisch im Moment wirklich ein Engpass? Wie viel würde es verbessern? Ist das Entfernen eines Index die beste Strategie, um dieses Problem zu beheben?Wird dies zu Problemen mit Datenbanktools und Frameworks (insbesondere ORMs) führen, bei denen für jede Tabelle ein Primärschlüssel und nicht nur ein eindeutiger Index erwartet wird? Für die Transaktionsreplikation ist ein Primärschlüssel für veröffentlichte Tabellen erforderlich .
Ist ein selbstdokumentierendes Datenbankschema wichtig?
Ermöglicht die Enge des Primärschlüsselindex trotz seiner eingeschränkten Verwendung dem Optimierer weiterhin, effizientere Pläne für bestimmte Abfragen zu erstellen? (
sys.dm_db_index_usage_stats
Zum Herausfinden verwenden.)Persönlich würde ich es nach Ihren Angaben so lange in Ruhe lassen, bis nachgewiesen werden kann, dass sowohl (a) der zusätzliche Index ein Problem darstellt als auch (b) das Entfernen die Lösung darstellt.
quelle
Der einzige Abfragetyp für diese Tabelle, der eine schlechtere (und nur geringfügig schlechtere) Leistung erzielt, ist der, der einen Bereich von KeyColumn-Werten anfordert, da diese Abfragen derzeit am besten von einer Indexsuche in Ihrer PK bedient werden.
Es ist zu berücksichtigen, dass die Kosten für die Prüfung der referenziellen Integrität für Tabellen, die auf diese Tabelle verweisen, höher sein werden (wiederum nur geringfügig höher).
Solange Sie sich um den nullbaren Aspekt kümmern, sollten Sie mit dem einen Index klar kommen.
Wenn es meine Datenbank wäre, würde ich wahrscheinlich den einzelnen eindeutigen Index wählen, wobei alle anderen Dinge gleich sind.
quelle
Wenn Sie einen Clustered-Index für KeyColumn haben, werden alle anderen Spalten implizit "abgedeckt", da es sich um einen Clustered-Index handelt. Sie erhalten also nichts, wenn Sie einen weiteren Index für KeyColumn hinzufügen. Tatsächlich verlangsamen Sie Ihre Einfügungen und beanspruchen mehr Platz.
Dies liegt daran, dass ein Clustered-Index kein Index als solcher ist, sondern nur eine Anweisung zum Speichern der Zeilen der Tabelle in der Reihenfolge des Index. Und wenn Sie eine Zeile mit dem Primärschlüssel erstellt haben, haben Sie alle anderen Spalten genau dort.
quelle
The table is clustered by another column entirely.