Unser Projekt betreibt eine sehr große, sehr komplizierte Datenbank. Vor ungefähr einem Monat haben wir festgestellt, dass der von indizierten Spalten mit Nullwerten verwendete Speicherplatz zu groß wurde. Als Antwort darauf schrieb ich ein Skript, das dynamisch alle einspaltigen Indizes durchsucht, die mehr als 1% der Nullwerte enthalten, und diese Indizes dann als gefilterte Indizes löscht und neu erstellt, sofern der Wert NICHT NULL ist. Dies würde Hunderte von Indizes in der gesamten Datenbank löschen und neu erstellen und in der Regel fast 15% des von der gesamten Datenbank verwendeten Speicherplatzes freigeben.
Jetzt habe ich zwei Fragen dazu:
A) Was sind die Nachteile der Verwendung gefilterter Indizes auf diese Weise? Ich würde davon ausgehen, dass dies nur die Leistung verbessern würde, aber gibt es Leistungsrisiken?
B) Beim Löschen und Neuerstellen der Indizes sind Fehler aufgetreten ( "Index XYZ kann nicht gelöscht werden, da er nicht vorhanden ist oder Sie keine Berechtigung haben" ), obwohl bei der anschließenden Überprüfung alles genau wie erwartet verlaufen ist. Wie kann das passieren?
Vielen Dank für jede Hilfe!
Bearbeiten: Als Antwort auf @Thomas Kejser
Hallo und danke, aber es stellte sich heraus, dass dies eine Katastrophe war. Zu der Zeit haben wir einige Dinge nicht verstanden wie:
- Während einer Abfrage erstellt SQLOS Indexpläne, bevor festgestellt wird, dass keine NULL-Werte zum Verknüpfen von Tabellenspalten verwendet werden können. IE, Sie müssen wirklich einen WHERE-Klauselfilter haben, der zum Index für jeden gefilterten Index passt, der in der Abfrage verwendet wird, oder der Index wird überhaupt nicht verwendet.
- Das Löschen und Erstellen von Indizes und das anschließende redundante Aktualisieren ihrer Statistiken reicht möglicherweise noch nicht aus, um die aktualisierten Pläne zu erstellen, von denen wir angenommen haben, dass sie dies tun würden. In einigen Fällen wird SQL Server aufgrund einer ausreichend hohen Arbeitslast gezwungen, die Pläne neu zu bewerten.
- Die Funktionalität des Ausführungsplaners weist einige Exoten auf, die allein durch gesunden Menschenverstand und Logik nur schwer zu bestimmen sind. Selbst mit Tausenden von Code-Behind-generierten Variationen verschiedener Abfragen können scheinbar nutzlose Indizes in einigen Statistiken und Abfrageplänen hilfreich sein, die letztendlich in kritischen Abfragen verwendet werden.
Am Ende wurden diese Änderungen rückgängig gemacht. Gefilterte Indizes sind also ein leistungsstarkes Werkzeug, aber Sie müssen wirklich genau verstehen, welche Daten aus diesen Spalten abgerufen werden. Wo normale Indizes neben den Speicherplatzproblemen eher einfach anzuwenden sind, stellen gefilterte Indizes sehr angepasste Lösungen dar. Sie sind sicherlich kein Ersatz für einen regulären Index, sondern eine Erweiterung für sie unter den besonderen Umständen, die sie benötigen.
Antworten:
Sehr interessanter Ansatz. Mein Upvote für die Kreativität.
Da Sie den Speicherplatz zurückgefordert haben, gehe ich davon aus, dass die ursprünglichen Indizes nicht mehr vorhanden sind. Die Nachteile von gefilterten Indizes sind dann:
In der Praxis bedeutet dies, dass Sie mit gefilterten Indizes äußerst vorsichtig sein müssen, da diese häufig zu schrecklichen Abfrageplänen führen. Ich würde nicht so weit gehen, sie als nutzlos zu bezeichnen, aber ich betrachte sie als Ergänzung zu herkömmlichen Indizes, nicht als Ersatz (wie Sie es versuchen).
quelle
Thomas Kejser beantwortet dieses Thema weit oben.
Ich habe gerade darüber nachgedacht, 2 Cent hinzuzufügen.
Ich habe gesehen, dass einige gefilterte Indizes nur verwendet werden (im Ausführungsplan angezeigt), wenn Sie die where-Klausel in Ihrer Abfrage genau mit dem where im gefilterten Index übereinstimmen.
Haben Sie versucht, indizierte Ansichten zu verwenden ? spärliche Spalten ?
Ich glaube, dass Sie, sofern Sie nur innere Gelenke haben, eine indizierte Ansicht erstellen können, die die where-Klausel (n) Ihrer gefilterten Indizes enthält, und dann stattdessen die Ansicht verwenden können.
Es kann mehr als eine Ansicht geben. Aber genau wie bei den nicht gruppierten Indizes verlangsamen zu viele das Schreiben.
Nach meiner Erfahrung hätten Sie gute Lesegewinne, müssten jedoch Schreibvorgänge (Einfügungen und Aktualisierungen) überwachen, insbesondere wenn die Tabellen an der Replikation beteiligt sind.
Soweit ich jedoch Ihr Hauptanliegen verstehe,
the null values
würde ich Ihnen SPARSE-Spalten in Ihren Indizes vorschlagen .Sparse-Spalten eignen sich besonders für gefilterte Indizes
Da ich spärliche Spalten beworben habe, würde ich mich nicht wohl fühlen, wenn ich Ihnen nicht auch über die Einschränkungen erzählen würde:
Und folglich
Betrachten Sie das Beispiel> einer Tabelle mit 600 spärlichen Spalten vom Typ bigint.
Weitere Details zum obigen Link, ich möchte diese Warnung jedoch auch hier posten:
Das SQL Server-Datenbankmodul verwendet das folgende Verfahren, um diese Änderung durchzuführen:
1 - Fügt der Tabelle eine neue Spalte in der neuen Speichergröße und im neuen Format hinzu.
2 - Aktualisiert und kopiert für jede Zeile in der Tabelle den in der alten Spalte gespeicherten Wert in die neue Spalte.
3 - Entfernt die alte Spalte aus dem Tabellenschema.
4 - Erstellt die Tabelle neu (wenn kein Clustered-Index vorhanden ist) oder erstellt den Clustered-Index neu, um den von der alten Spalte verwendeten Speicherplatz zurückzugewinnen.
quelle