Database
 sql >> Datenbank >  >> RDS >> Database

Datenbankoptimierung:Indizes

Mir ist aufgefallen, dass nur sehr wenige Leute verstehen, wie Indizes in SQL Server funktionieren, insbesondere eingeschlossene Spalten. Dennoch sind Indizes die großartige Möglichkeit, Abfragen zu optimieren. Auf die mitgelieferten Spalten bin ich zunächst auch nicht gekommen, aber meine Experimente haben gezeigt, dass sie sehr nützlich sind.

Angenommen, wir haben die folgende Tabelle und Abfrage:

CREATE TABLE Person (
 PersonID int,
 FirstName varchar(100),
 LastName varchar(100),
 Age int,
 …
 …
)

SELECT FirstName, LastName, Age
FROM Person
WHERE FirstName = 'John' and LastName = 'Smith'

Es ist klar, dass PersonID ein Primärschlüssel ist. Angenommen, wir haben einen Index mit Vor- und Nachnamen, nennen wir ihn IX_Person_FirstNameLastName. Der Ausführungsplan für eine solche Abfrage sieht wie folgt aus:

  1. Auffinden aller Zeilen mit den angegebenen Vor- und Nachnamen mit Hilfe des Indexbaums IX_Person_FirstNameLastName
  2. Den tatsächlichen Standort der Linie auf der Scheibe auf den Indexblättern erkennen, zum tatsächlichen Standort gehen und das Alter ablesen.

Nehmen wir nun an, dass diese Abfrage ziemlich häufig ausgeführt wird. Wir müssen jedes Mal 2 Schritte ausführen. Kann es optimiert werden? Im Fall von MS SQL Server ist dies kein Problem – Sie können Werte mit Hilfe der INCLUDE-Option direkt in den Index aufnehmen.

CREATE INDEX IX_PERSON ON Person
( 
 FirstName,
 LastName
) 
INCLUDE(Age)

Jetzt wird dieses Feld nicht während der Indizierung verwendet, sondern in den Index aufgenommen. Welche Probleme können wir in dieser Hinsicht haben? Wenn wir eine Tabelle nach einem bestimmten Feld indizieren, muss der Datenbankserver einen Indexbaum nach diesem Feld aufbauen. Das bedeutet, dass wir den Indexbaum ändern müssen, wenn wir den Wert ändern. Wenn Werte intensiv geändert werden, wird dies zu einer problematischen und schwierigen Aufgabe für den Server. Wenn die Aktualisierung zu umfangreich wird, ist es manchmal einfacher, den Index zu löschen. Der Index optimiert die Suche erheblich, wirkt sich jedoch negativ auf die Einfüge-, Lösch- und Aktualisierungsvorgänge aus.
Wenn ein Feld einfach in einen Index aufgenommen wird, wird es während des Aufbaus eines Indexbaums nicht verwendet und beeinflusst ihn nicht, aber die Wert kann leicht auf dem Blatt dieses Baumes gefunden werden. Bei einer Suche nach Nach- und Vornamen sucht der Server nach allen Vor- und Nachnamen aus dem Baum, und wenn er das Blatt erreicht (findet den erforderlichen Indexwert), dann zusätzlich den Zeiger auf den physischen Ort Neben den Zeilenwerten enthält es auch Feldwerte, die im Index enthalten sind. Das bedeutet, dass es nicht notwendig ist, den zweiten Schritt zu machen, um zum physischen Standort der Leitung zu wechseln und sie von dort zu lesen.

Da Sie den Baum nicht ändern müssen, wenn Sie die Altersdaten ändern, hat all dieses Zeug keinen großen Einfluss auf die Datenänderungsoperationen. Wir müssen den Index nicht ändern, wir müssen nur die Werte auf dem Baumblatt ändern. Deshalb wird selbst eine massive Änderung des Altersfelds keinen großen Einfluss auf die Leistung haben. Es wird sicherlich Auswirkungen haben, aber nicht so sehr.

Die Werte des Clustered Index werden meines Wissens automatisch in die Blattebene aufgenommen, dies muss aber bei der Spezifikation geprüft werden.

Wann also ist die Verwendung der enthaltenen Felder von Vorteil? Wenn sie häufig in Abfrageergebnissen verwendet werden, aber hin und wieder geändert werden. Ein Beispiel ist eine Tabelle mit Banktransaktionen. Eine solche Tabelle kann aus folgenden Feldern bestehen:Kontonummer, Art der Transaktion, Datum, Summe. Es macht keinen Sinn, nach der Summe zu indizieren, aber wir können sie in den Index aufnehmen, was die Abfrage erheblich beschleunigt.

Um den tatsächlichen Effekt der Indizierung abzurufen, sollten die Abfragen nicht alle Felder auswählen, d. h. wir sollten die SELECT * FROM-Tabelle vergessen. Berechnen Sie immer nur die Felder neu, die Sie wirklich brauchen. Und wenn ihre Werte in den Index gelangen, kann die Ausführungsgeschwindigkeit ziemlich hoch sein.

Nützliches Tool:

dbForge Index Manager – praktisches SSMS-Add-in zum Analysieren des Status von SQL-Indizes und Beheben von Problemen mit der Indexfragmentierung.