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?
quelle
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?
Wir werden uns einige der Gründe genauer ansehen und auch einige der allgemeinen Einschränkungen der Funktion erläutern.
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.
Fehlende Indexschlüsselspalten werden aus Spalten generiert, die zum Filtern von Ergebnissen verwendet werden, z. B .:
Fehlender Index Eingeschlossene Spalten werden aus Spalten generiert, die von der Abfrage benötigt werden, z. B .:
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;
Diese Gruppierungsabfrage erfolgt auch nicht vor Ort.
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
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.
Entspann dich, Bucko. Wir kommen dorthin.
Wenn Sie TF 2330 aktivieren , werden fehlende Indexanforderungen nicht protokolliert. Um herauszufinden, ob dies aktiviert ist, führen Sie Folgendes aus:
DBCC TRACESTATUS;
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 .
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.
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);
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.
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:
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:
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 ...
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);
Und deutlich weniger liest:
Tabelle 'Beiträge'. Scananzahl 1, logische Lesevorgänge 5
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.