Warum fehlen in SQL Server keine Indexanforderungen in den DMVs oder Abfrageplänen?

14

Ich habe eine SQL Server-Datenbank, in der die Abfragen ziemlich langsam sind und in der viel gesperrt und blockiert wird.

Wenn ich mir die fehlenden Index-DMVs und Abfragepläne ansehe, gibt es keine Vorschläge.

Warum das?

Erik Darling
quelle

Antworten:

17

Es gibt viele Gründe, warum Sie möglicherweise keine fehlenden Indexanforderungen haben!

Wir werden uns einige der Gründe genauer ansehen und auch einige der allgemeinen Einschränkungen der Funktion erläutern.

Allgemeine Einschränkungen

Erstens aus: Einschränkungen der fehlenden Indizes Feature :

  • Es gibt keine Reihenfolge für Spalten an, die in einem Index verwendet werden sollen.

Wie in dieser Frage und Antwort angegeben: Wie ermittelt SQL Server die Schlüsselspaltenreihenfolge in fehlenden Indexanforderungen? Die Reihenfolge der Spalten in der Indexdefinition wird durch das Vergleichselement Gleichheit vs. Ungleichheit und dann durch die Ordnungsposition der Spalten in der Tabelle vorgegeben.

Es gibt keine Vermutungen zur Selektivität und möglicherweise ist eine bessere Reihenfolge verfügbar. Es ist Ihre Aufgabe, das herauszufinden.

Sonderindizes

Fehlende Indexanforderungen decken auch keine speziellen Indizes ab, wie z.

  • Gruppiert
  • Gefiltert
  • Partitioniert
  • Komprimiert
  • XML-ed
  • Spatial-ed
  • Columnstore-d
  • Indizierte Ansicht-ed

Welche Spalten werden berücksichtigt?

Fehlende Indexschlüsselspalten werden aus Spalten generiert, die zum Filtern von Ergebnissen verwendet werden, z. B .:

  • JOINs
  • WHERE-Klausel

Fehlender Index Eingeschlossene Spalten werden aus Spalten generiert, die von der Abfrage benötigt werden, z. B .:

  • WÄHLEN
  • GRUPPIERE NACH
  • SORTIEREN NACH

Auch wenn Spalten, nach denen Sie sortieren oder die Sie gruppieren, häufig als Schlüsselspalten nützlich sein können. Dies geht auf eine der Einschränkungen zurück:

  • Es ist nicht vorgesehen, eine Indexierungskonfiguration zu optimieren.

Beispielsweise registriert diese Abfrage keine fehlende Indexanforderung, obwohl das Hinzufügen eines Index für LastAccessDate die Notwendigkeit des Sortierens (und Verschüttens auf die Festplatte) verhindern würde.

SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;

NÜSSE

Diese Gruppierungsabfrage erfolgt auch nicht vor Ort.

SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location

NÜSSE

Das klingt nicht sehr hilfreich!

Nun ja, aber es ist besser als nichts. Stellen Sie sich fehlende Indexanforderungen wie ein weinendes Baby vor. Sie wissen, dass es ein Problem gibt, aber es liegt an Ihnen als Erwachsener, herauszufinden, was dieses Problem ist.

Du hast mir immer noch nicht gesagt, warum ich sie nicht habe ...

Entspann dich, Bucko. Wir kommen dorthin.

Fahnen verfolgen

Wenn Sie TF 2330 aktivieren , werden fehlende Indexanforderungen nicht protokolliert. Um herauszufinden, ob dies aktiviert ist, führen Sie Folgendes aus:

DBCC TRACESTATUS;

Index-Neuerstellungen

Durch die Neuerstellung von Indizes werden fehlende Indexanforderungen gelöscht. Bevor Sie also jeden Index neu aufbauen, denken Sie an die Informationen, die Sie jedes Mal löschen, wenn Sie dies tun.

Vielleicht möchten Sie auch darüber nachdenken, warum das Defragmentieren Ihrer Indizes sowieso nicht hilft . Es sei denn, Sie verwenden Columnstore .

Indizes hinzufügen, entfernen oder deaktivieren

Durch Hinzufügen, Entfernen oder Deaktivieren eines Index werden alle fehlenden Indexanforderungen für diese Tabelle gelöscht. Wenn Sie mehrere Indexänderungen in derselben Tabelle durchführen, müssen Sie sicherstellen, dass Sie sie alle ausschreiben, bevor Sie sie vornehmen.

Trivialpläne

Wenn ein Plan einfach und die Auswahl des Indexzugriffs offensichtlich und die Kosten niedrig genug sind, erhalten Sie einen einfachen Plan.

Dies bedeutet effektiv, dass der Optimierer keine kostenbasierten Entscheidungen treffen musste.

Über Paul White :

Die Details, welche Abfragetypen von Trivial Plan profitieren können, ändern sich häufig, aber Dinge wie Verknüpfungen, Unterabfragen und Ungleichheitsprädikate verhindern diese Optimierung im Allgemeinen.

Wenn ein Plan trivial ist, werden zusätzliche Optimierungsphasen nicht untersucht und fehlende Indizes werden nicht angefordert .

Sehen Sie den Unterschied zwischen diesen Abfragen und ihren Plänen :

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;

SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);

NÜSSE

Der erste Plan ist trivial, und es wird keine Anforderung angezeigt. Es kann Fälle geben, in denen Fehler verhindern, dass fehlende Indizes in Abfrageplänen angezeigt werden. Sie werden jedoch in der Regel zuverlässiger in den fehlenden Index-DMVs protokolliert.

Erreichbarkeit

Prädikate, bei denen das Optimierungsprogramm einen Index selbst mit einem Index nicht effizient verwenden kann, können die Protokollierung verhindern.

Dinge, die im Allgemeinen nicht SARGable sind, sind:

  • In Funktionen eingeschlossene Spalten
  • Spalte + SomeValue = SomePredicate
  • Column + AnotherColumn = SomePredicate
  • Spalte = @Variable ODER @Variable IST NULL

Beispiele:

SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;


SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000


SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000


DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo 
      OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;

Bei keiner dieser Abfragen werden fehlende Indexanforderungen registriert. Weitere Informationen hierzu finden Sie unter den folgenden Links:

Sie haben bereits einen Okay-Index

Nehmen Sie diesen Index:

CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);

Es sieht in Ordnung für diese Abfrage aus:

SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND   p.CreationDate < '20181231'
AND   p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;

Der Plan ist eine einfache Suche ...

NÜSSE

Da sich die führende Schlüsselspalte jedoch auf das weniger selektive Prädikat bezieht, leisten wir am Ende mehr Arbeit, als wir sollten:

Tabelle 'Beiträge'. Scan-Anzahl 13, logische Lesevorgänge 136890

Wenn wir die Reihenfolge der Indexschlüsselspalten ändern, machen wir viel weniger Arbeit:

CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);

NÜSSE

Und deutlich weniger liest:

Tabelle 'Beiträge'. Scananzahl 1, logische Lesevorgänge 5

SQL Server erstellt Indizes für Sie

In bestimmten Fällen erstellt SQL Server einen Index im laufenden Betrieb über eine Index-Spool. Wenn eine Index-Spool vorhanden ist, wird eine fehlende Indexanforderung nicht angezeigt. Sicherlich ist es eine gute Idee, den Index selbst hinzuzufügen, aber Sie können sich nicht darauf verlassen, dass SQL Server Sie dabei unterstützt, dies herauszufinden.

NÜSSE

Erik Darling
quelle