Ich wurde gebeten, eine sehr belebte Tabelle zu überprüfen und Verbesserungsmöglichkeiten zu ermitteln.
Ich habe nur sehr begrenzte Möglichkeiten, die Tabelle nur die Indizes zu ändern.
Tabelleninformationen
- 240 Spalten
- ~ 5 Millionen Zeilen
- Gelesen und aktualisiert von etwa 30 Anwendungen, die von Websites bis zu Abfrageanwendungen reichen.
- Jede Zeile repräsentiert einen Vertrag und seinen Status basierend auf drei Flags (Varchars der Größe 5, 8 und 8).
- Der Lebenszyklus einer Zeile verläuft von Anfang bis Ende durch diese drei Flags und ist schließlich abgeschlossen.
- Eine Zeile wird normalerweise 10 bis 30 Mal während dieses Lebenszyklus aktualisiert oder geändert.
- Der Primärschlüssel ist eine Kombination aus einer ID-Spalte, einer Guid-Spalte und einer Unternehmensspalte.
- Die Tabelle enthält mehr als 40 Indizes, von denen die meisten doppelt vorhanden und nicht verwendet sind. Dies basiert auf der
sys.dm_db_index_usage_stats
DMV , die in den letzten 7 Wochen zweimal pro Woche ausgeführt wurde.
Der aktuelle Clustered-Index für diese Tabelle enthält fünf Spalten:
- Unternehmensspalte (50 verschiedene Werte)
- Regionsspalte (21 verschiedene Werte)
- FlagA-Spalte (8 verschiedene Werte)
- FlagB-Spalte (24 verschiedene Werte)
- FlagC-Spalte (5 verschiedene Werte)
Nach meinem Verständnis sollte ein Clustered-Index den folgenden Eigenschaften entsprechen. Quelle
- Einzigartig
- Statisch
- Eng
- Immer größer.
Der aktuelle Clustered-Index ist keiner davon.
- Es gibt keine eindeutige ID.
- Die drei Flags werden ständig aktualisiert.
- Zu jedem Zeitpunkt können 5000 Zeilen vorhanden sein, die für alle 5 Spalten dieselben Werte haben.
Daher ging ich davon aus, dies mit einem Clustered-Index für die Id
Spalte zu korrigieren - einer Ganzzahl, die KEINE Identität ist, sondern über eine Zählertabelle verwaltet wird (Wert lesen, 1 hinzufügen, Zählertabelle aktualisieren).
Ich habe einen Clustered-Index für das erstellt Id
, ohne den Primärschlüssel zu verwenden, da ich der Meinung war, dass das Hinzufügen der Guid- und Company-Spalte keinen Nutzen bringen würde.
Ich habe dann einen nicht gruppierten Index erstellt, der das Unternehmen, die Region und 3 Flags enthält. In einer Testumgebung sahen die Statistiken gut aus, user_updates
waren niedriger usw. Aber die Gesamtleistung der Anwendungen für diese Tabelle war schrecklich. Die häufigsten Abfragen für diese Tabelle sind:
SELECT *
FROM table
WHERE ID = 1234;
Und
SELECT *
FROM table
WHERE Company = 'company'
AND Region = 'region'
AND flagA= 'A'
AND flagB = 'B'
AND flagC = 'C';
- Was habe ich vermisst? Gibt es Ausnahmen zu den oben genannten Clustered-Index-Regeln?
- Würde der Clustered-Index davon profitieren, das Unternehmen und die Region zur ID hinzuzufügen?
Ich verstehe, wenn der Clustered-Index nicht statische Werte enthält, muss er sich selbst und die anderen nicht gruppierten Indizes ständig neu organisieren. Zu diesem Zeitpunkt haben wir noch 40 plus ..., um später entfernt zu werden. Hätte ich dort nicht einen Gewinn gesehen?
Informationen hinzugefügt.
- Beide Umgebungen sind SQL Server 2008 R2
- Haben Sie das gleiche Betriebssystem, Speicher usw.
- Der einzige Unterschied war der Clustered-Index.
- Ich habe das geschrieben
SELECT *
, um im obigen Beispiel kurz zu sein. - Test- und Produktionsumgebung sind "gleich", so gut sie können: Die Produktion war einer höheren Last ausgesetzt, aber auf beiden wurden dieselben Anwendungen ausgeführt, die Last wurde ausgeglichen usw. Der Test war erheblich langsamer.
- Wir haben anderthalb Wochen mit dem neuen Cluster gearbeitet, bevor wir zum ursprünglichen Setup zurückgekehrt sind. Zu Beginn wurden die Statistiken aktualisiert und bestimmte gespeicherte Prozesse neu kompiliert, als die langsame Leistung einsetzte.
- Ich bin damit einverstanden, dass mit dem mehrspaltigen Index zumindest die Tabelle besser organisiert war als nur auf
Id
. Ich möchte erneut versuchen, Unternehmen, Region und ID als CI zu verwenden, aber die drei Flaggen weglassen.
Was habe ich vermisst?