Warum erlauben indizierte Ansichten keine nicht eindeutigen Clustered-Indizes?

12

Ich habe versucht, indizierte Ansichten zu verwenden, um die Leistung einiger unserer am häufigsten verwendeten Ansichten zu steigern.

Indizierte Ansichten unterstützen jedoch keine nicht eindeutigen Clustered-Indizes, was ein wenig gegen die vom Rest der Datenbankstruktur festgelegte Priorität verstößt.

Hier ist zum Beispiel eine vereinfachte Version einiger unserer Tabellen.

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID

Die Indizes befinden sich auf Groups.GroupID (nicht gruppiert) und Users.GroupID (gruppiert). Der Clusterschlüssel, der sich in der Tabelle "Benutzer" in der Gruppe "ID" befindet, da am häufigsten ein Bereich von Benutzern aus einer bestimmten Gruppe abgerufen wird. Offensichtlich hätten Sie mehrere Benutzer pro Gruppe, sodass dieser Clustered-Index nicht eindeutig ist.

Dies lässt mich ein wenig unsicher, wie ich dieser Priorität beim Indizieren meiner Ansichten wie diesem Beispiel folgen soll, da ich keinen nicht eindeutigen Clustered-Index haben kann.

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2

Tatsächlich ist der einzige Wert in dieser Ansicht, der immer eindeutig wäre, die Spalte ConsumableID, sodass ich keine andere Wahl habe, wo ich meinen Index platzieren soll.

Warum erlauben Ansichten keine nicht eindeutigen Clustered-Indizes, wenn dies bei regulären Tabellen der Fall ist?

Freundlich
quelle
3
Am Ende dieser Seite finden Sie eine sehr kurze Erklärung mit dem Titel "Warum muss der erste Index einer Ansicht CLUSTERED und EINZIGARTIG sein?". aber es macht nicht viel Detail. Es würde mich auf jeden Fall interessieren, eine ausführlichere Erklärung zu hören.
Steve Pettifer
5
Ein paar Kommentare: 1 - Es gibt keinen Grund, warum Sie nicht gruppieren können (GroupID, UserID). Beschränken Sie sich nicht auf eine einzelne Spalte für den Schlüssel. 2 - Ich stelle mir vor, dass die Einschränkung für eine Ansicht darin besteht, dass dies ein zusätzliches Datenobjekt ist, für das Zeilen leicht mit den NC-Indizes verknüpft werden müssen. Für eine Tabelle wird dem nicht eindeutigen CI-Schlüssel ein int angehängt, aber ich denke, dass dies bei einer indizierten Ansicht schwieriger wäre, da es sich nicht um eine tatsächliche Tabelle handelt, sondern eine tatsächliche Tabelle reflektieren muss.
JNK

Antworten:

22

Die folgende Erklärung wird in diesem technischen Artikel von Microsoft gegeben :

Warum muss der erste Index einer Ansicht CLUSTERED und EINZIGARTIG sein?

Es muss EINZIGARTIG sein, um eine einfache Suche nach Datensätzen in der Ansicht nach Schlüsselwerten während der Pflege der indizierten Ansicht zu ermöglichen und die Erstellung von Ansichten mit Duplikaten zu verhindern, für deren Pflege eine spezielle Logik erforderlich wäre. Es muss geclustert werden, da nur ein gruppierter Index die Eindeutigkeit erzwingen und die Zeilen gleichzeitig speichern kann.

SQL Server verwendet ein Delta-Algebra-System, um indizierte Ansichten mit den Basisdaten Schritt zu halten. Außerdem werden für jede DML-Abfrage, die eine oder mehrere indizierte Ansichten betrifft, automatisch Abfrageplanoperatoren für die Ansichtsverwaltung integriert. Ein eindeutiger Clustered-Index in der Ansicht vereinfacht die Implementierungsdetails erheblich.

Die aktuelle Anordnung ermöglicht die Integration von Formen des Wartungsoperatorbaums mit fester Form in den Basis-DML-Abfragebaum, wodurch eine Orthogonalität bereitgestellt wird, die auch das Testen vereinfacht. Letztendlich könnten indizierte Ansichten eines Tages erweitert werden, um nicht eindeutige Clustered-Indizes zu unterstützen. Andererseits sind alle Dinge bei unbegrenzter Zeit und unbegrenzten Ressourcen möglich (beides gilt zum Zeitpunkt des Schreibens nicht für das SQL Server-Entwicklungsteam).

Ein Beispiel, das zeigt, wie komplex das Erstellen von Aktualisierungsabfrageplänen werden kann und wie leicht sich subtile Fehler einschleichen können, finden Sie in diesem Beispiel eines Fehlers , der bei MERGEindizierten und gefilterten Indizes auftritt (eine Funktion, die eine enge Verbindung zu indizierten Ansichten aufweist).

Paul White 9
quelle
2
Ein ähnlicher Fehler kann auftreten, wenn Sie versuchen, eine indizierte Ansicht zu aktualisieren, die eine GROUP BYKlausel enthält, aber nicht alle Gruppierungsausdrücke Schlüssel im Clustered-Index sind. Es ist gültig ab SQL Server 2014.
Quassnoi
4

In SQL Server müssen alle Indexschlüssel intern eindeutig sein. Dies ist erforderlich, um Sperrschlüssel zu erhalten, die genau eine Zeile adressieren. Es ist auch für die Indexpflege erforderlich. Stellen Sie sich eine NCI in einer Spalte vor, die nur einen Wert enthält (100% Duplikate). Wenn eine Zeile aus der Tabelle gelöscht wird, muss die Speicher-Engine die entsprechende NCI-Zeile finden und ebenfalls löschen. Wenn alle NCI-Zeilen nicht unterscheidbar sind, wäre dies unmöglich.

Sie sehen also, dass das CI in einer Ansicht (intern) eindeutig sein muss, damit die Engine funktioniert.

Wenn Sie einen Index nicht eindeutig machen, macht SQL Server ihn intern immer noch eindeutig. Bei einer NCI in einer Heap-Tabelle wird das Zeilenlesezeichen angehängt. Bei einem nicht eindeutigen CI wird eine Eindeutigkeitsspalte hinzugefügt. Bei einem NCI in einer Tabelle mit einem CI werden alle CI-Schlüsselspalten angehängt, die Sie selbst noch nicht angegeben haben (dies kann den Eindeutiger einschließen).

Es gibt keine offensichtliche Spalte, die im Falle einer indizierten Ansicht angehängt werden könnte. SQL Server kann dies also nicht automatisch tun.

Normalerweise ist es für einen Menschen ziemlich offensichtlich, welche Spalten Sie hinzufügen können, damit die Ansicht über einen eindeutigen Satz von Spalten verfügt, die im CI verwendet werden können. Dies sind normalerweise die PK- oder CI-Spalten einer der zugrunde liegenden Tabellen. Wenn die Ansicht einen GROUP BYhat, indizieren Sie normalerweise die Gruppierungsschlüssel.

usr
quelle
2
Ich empfehle dringend, die Formulierung dieser Antwort zu überarbeiten. Obwohl es einen gültigen Punkt in Bezug auf die ursprüngliche Frage enthält, könnte es so aussehen, als ob es darauf hindeutet, dass alle nicht eindeutigen Indizes Eindeutigkeiten enthalten, was nicht der Fall ist.
Spaghettidba
@spaghettidba danke, das habe ich nicht bemerkt. Hoffe es ist jetzt besser.
usr
Tut mir leid, nicht jetzt. Sie mischen zwei Dinge zusammen. Nicht gruppierte Indizes müssen nicht eindeutig sein und sind intern nicht eindeutig: Sie machen diesen Punkt nicht klar genug. Alles, was Sie in Ihrer Antwort sagen, gilt nur für Clustered-Indizes.
Spaghettidba
@spaghettidba NCIs sind intern immer eindeutig. Sie können immer alle CI-Schlüssel als Teil eines Abfrageplans ausgeben. Siehe pastebin.com/vkGHpCsR Die NCI-Datenseite enthält beide Spalten.
usr
Ich sehe, woher du kommst. Mehrere Blätter können denselben Indexschlüssel verwenden, der Clustering-Schlüssel ist jedoch immer in NCIs enthalten. Ist es genug zu sagen, dass sie intern immer einzigartig sind? Das glaube ich nicht.
Spaghettidba