Benötige ich separate Indexe für jede Abfrageart oder Funktioniere ein Multi-Säulen-Index?

dba.stackexchange https://dba.stackexchange.com/questions/197

  •  16-10-2019
  •  | 
  •  

Frage

Ich kenne die Antwort auf diese Frage schon etwas, aber ich habe immer das Gefühl, dass ich das Thema aufgreifen muss.

Mein grundlegendes Verständnis ist, dass im Allgemeinen ein einzelner Index, der nur alle Felder enthält, die Sie möglicherweise zu einem bestimmten Zeitpunkt abfragen/sortieren, wahrscheinlich nicht nützlich sein wird, aber ich habe diese Art von Dingen gesehen. Wie in dachte jemand: "Nun, wenn wir all dieses Zeug in einen Index stecken, kann die Datenbank sie verwenden, um das zu finden, was sie braucht", ohne jemals einen Ausführungsplan für einige der tatsächlichen Abfragen gesehen zu haben, die ausgeführt werden.

Stellen Sie sich einen Tisch wie so vor:

id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime

Ich könnte einen einzelnen Index einschließlich der sehen name, customerId und dateCreated Felder.

Mein Verständnis ist jedoch, dass ein solcher Index nicht in einer Abfrage wie zum Beispiel verwendet wird:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Für eine solche Frage scheint es mir, dass eine bessere Idee ein Index ist, einschließlich der customerId und dateCreated Felder mit dem customerId Feld ist 'zuerst'. Dies würde einen Index erstellen, in dem die Daten so organisiert werden würden, dass diese Abfrage schnell finden könnte, was sie benötigt - in der Reihenfolge, die sie benötigt.

Eine andere Sache, die ich vielleicht so häufig wie die erste sehe, sind individuelle Indizes in jedem Feld. Also jeweils einer auf name, customerId und dateCreated Felder.

Im Gegensatz zum ersten Beispiel scheint mir diese Art von Anordnung manchmal zumindest teilweise nützlich zu sein. Der Ausführungsplan der Abfrage kann zeigen, dass er zumindest den Index auf dem verwendet customerId So wählen Sie die Datensätze aus, verwendet jedoch nicht den Index mit dem dateCreated Feld, um sie zu sortieren.


Ich weiß, dass dies eine breite Frage ist, da die spezifische Antwort auf eine bestimmte Abfrage in einem bestimmten Satz von Tabellen normalerweise darin besteht Konto. Ich weiß auch, dass es davon abhängt, wie oft eine Abfrage ausgeführt werden kann, anstatt einen bestimmten Index dafür aufrechtzuerhalten.

Aber ich nehme an, was ich frage, ist ein allgemeiner "Ausgangspunkt" für Indizes. Ist die Idee, spezifische Indizes für spezifische, häufig aufgefüllte Abfragen und die Felder in der Where oder Ordnung durch Klauseln zu haben?

War es hilfreich?

Lösung

Sie haben Recht, da Ihre Beispielabfrage diesen Index nicht verwenden würde.

Der Query -Planer erwägt einen Index, wenn:

  • Alle darin enthaltenen Felder werden in der Abfrage verwiesen
  • Einige der Felder, die von Anfang an beginnen

Es kann nicht in der Lage sein, Indizes zu verwenden, die mit einem von der Abfrage verwendeten Feld beginnen.

Also für dein Beispiel:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Es würde Indizes wie:

[customerId]
[customerId], [dateCreated]
[customerId], [dateCreated], [name]

aber nicht:

[name], [customerId], [dateCreated]

Wenn es beides gefunden wurde [customerId] und [customerId], [dateCreated], [name] Die Entscheidung, eine gegenüber den anderen zu bevorzugen, hängt von den Indexstatistiken ab, die von den Schätzungen des Datenbilanzs in den Feldern abhängen. Wenn [customerId], [dateCreated] wurden definiert, es sollte vorziehen, dass Sie den anderen beiden, sofern Sie einen bestimmten Index -Hinweis für das Gegenteil geben.

Es ist nicht ungewöhnlich, einen Index für jedes Feld in meiner Erfahrung definiert zu sehen, obwohl dies selten optimal ist, da die zusätzliche Verwaltung erforderlich ist Sie werden möglicherweise nie gebraucht - aber wenn Ihr DB schreibhaarige Lasten nicht sieht, wird die Leistung auch mit den überschüssigen Indizes nicht schlecht stinken.

Spezifische Indizes für häufige Abfragen, die aufgrund von Tabellen- oder Indexscannen ansonsten langsam wären, sind im Allgemeinen eine gute Idee, obwohl Sie sie nicht übertreiben, da Sie ein Leistungsproblem gegen ein anderes austauschen könnten. Wenn Sie definieren [customerId], [dateCreated] Denken Sie beispielsweise als Index daran, dass der Abfrageberger in der Lage ist, dies für Abfragen zu verwenden, die einen Index für gerade verwenden würden [customerId] Falls vorhanden. Während der Verwendung nur [customerId] Wäre etwas effizienter als die Verwendung des zusammengesetzten Index Dies kann gemindert werden, indem er zwei Indizes hat, die in RAM um einen Platz in RAM konkurrieren (wenn Ihr gesamtes normales Arbeitssatz einfach in RAM passt, ist dieser zusätzliche Speicherwettbewerb möglicherweise kein Problem) .

Andere Tipps

Um Ihre ursprüngliche Frage zu beantworten, müssen die Indizes um die entworfen werden Abfragen, nicht nur die Tisch. Die Reihenfolge der Felder im Index ist von entscheidender Bedeutung. Das Entwerfen eines einzelnen Index für mehrere Abfragen ist schwieriger, und Sie müssen Kompromisse erzielen.

In Bezug auf Ihren zweiten Punkt sind eine Reihe von Indizes auf einzelnen einzelnen Feldern ärgerlich häufig. Ich sehe es die ganze Zeit in meiner Umgebung und es ist normalerweise eine rote Fahne für mich, dass das Entwicklungsteam nicht mit einem DBA gearbeitet hat, um die richtigen Indizes zu entwerfen.

Meine Strategie zum Entwerfen von Indizes ist der Index:

  • Felder, die in Wo (in der Reihenfolge der Selektivität) verwendet werden
  • Felder verwendet in Ordnung von
  • Fügen Sie andere Felder (falls erforderlich) ein, um einen Deckungsindex zu erstellen

Also für dein Beispiel:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Ich würde wahrscheinlich einen Index auf (CustomerID, datecroated) enthalten (ID, Name). Dieser Covering Index bedeutet, dass die Abfrage niemals die ursprüngliche Tabelle treffen muss, was die Leistung erheblich verbessert.

Dieses Beispiel ist fast zu Einfach. Ein naiver Index für Just (CustomerID) würde sich fast genauso gut abgeben (vorausgesetzt, jeder Kunde hat nur einen einzelnen Repräsentanten, so dass nur eine einzige Suche nach einem Lesezeichen in die Tabelle erforderlich ist). Es könnte auch sogar vorteilhaft sein, tatsächlich a zu tun zusammengeklustert Index auf (CustomerID, ID), je nachdem, welche anderen Abfragen gegen die Tabelle ausführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top