Optimieren nicht gruppierter Indizes mit fehlenden Indexvorschlägen

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

Das Feature "Fehlende Indizes" ist ein einfaches Tool zum Auffinden fehlender Indizes, die die Abfrageleistung erheblich verbessern können. In diesem Artikel wird beschrieben, wie Sie Vorschläge für fehlende Indizes verwenden, um Indizes effektiv zu optimieren und die Abfrageleistung zu verbessern.

Einschränkungen der Funktion für fehlende Indizes

Wenn der Abfrageoptimierer einen Abfrageplan generiert, analysiert er, welche Indizes für eine bestimmte Filterbedingung am besten geeignet sind. Wenn die besten Indizes nicht vorhanden sind, generiert der Abfrageoptimierer trotzdem einen Abfrageplan mit den am wenigsten kostspieligen verfügbaren Zugriffsmethoden, speichert aber außerdem Informationen zu diesen Indizes. Die Funktion für fehlende Indizes ermöglicht den Zugriff auf diese Informationen über die bestmöglichen Indizes, sodass Sie entscheiden können, ob sie implementiert werden sollen.

Die Abfrageoptimierung ist ein zeitkritischer Prozess, daher gibt es Einschränkungen für die Funktion für fehlende Indizes. Es gelten einige Einschränkungen, u. a. folgende:

  • Vorschläge für fehlende Indizes basieren auf Schätzungen, die während der Optimierung einer einzelnen Abfrage vor der Abfrageausführung vorgenommen wurden. Vorschläge für fehlende Indizes werden nach der Abfrageausführung nicht getestet oder aktualisiert.
  • Die Funktion für fehlende Indizes schlägt nur nicht gruppierte, datenträgerbasierte Rowstore-Indizes vor. Eindeutige und gefilterte Indizes werden nicht vorgeschlagen.
  • Schlüsselspalten werden vorgeschlagen, der Vorschlag gibt aber keine Reihenfolge für diese Spalten an. Informationen zum Sortieren von Spalten finden Sie im Abschnitt Anwenden von Vorschlägen zu fehlenden Indizes in diesem Artikel.
  • Einbezogene Spalten werden vorgeschlagen, aber SQL Server führt keine Kosten-Nutzen-Analyse zur Größe des resultierenden Indexes durch, wenn eine große Anzahl einbezogener Spalten vorgeschlagen wird.
  • Fehlende Indexanforderungen bieten möglicherweise ähnliche Indizes in derselben Tabelle und Spalte(n) für Abfragen. Es ist wichtig, Indexvorschläge zu überprüfen und nach Möglichkeit zu kombinieren.
  • Für triviale Abfragepläne werden keine Vorschläge gemacht.
  • Die Kosteninformationen sind weniger genau, wenn die Abfragen nur Ungleichheitsprädikate enthalten.
  • Vorschläge werden für maximal 600 fehlende Indexgruppen gesammelt. Nachdem dieser Schwellenwert erreicht wurde, werden keine indexgruppendaten mehr erfasst.

Aufgrund dieser Einschränkungen werden Vorschläge zu fehlenden Indizes bei der Durchführung von Indexanalysen, Entwurf, Optimierung und Tests am besten als eine von mehreren Informationsquellen behandelt. Vorschläge für fehlende Indizes sind keine Anweisungen, Indizes genau wie vorgeschlagen zu erstellen.

Hinweis

Azure SQL-Datenbank bietet automatische Indexoptimierung. Bei der automatischen Indexoptimierung wird maschinelles Lernen verwendet, um mithilfe von KI horizontal aus allen Datenbanken in Azure SQL-Datenbank zu lernen und die Optimierungsaktionen dynamisch zu verbessern. Die automatische Indexoptimierung beinhaltet einen Überprüfungsprozess, um sicherzustellen, dass die Workloadleistung durch die erstellten Indizes positiv verbessert wird.

Anzeigen von Empfehlungen zu fehlenden Indizes

Die Funktion für fehlende Indizes setzt sich aus zwei Komponenten zusammen:

  • Dem Element MissingIndexes im XML-Code von Ausführungsplänen. Dies ermöglicht das Korrelieren von Indizes, die der Abfrageoptimierer als fehlend ansieht, mit den Abfragen, für die sie fehlen.
  • Eine Gruppe dynamischer Verwaltungssichten (DMV), die abgefragt werden können, um Informationen über fehlende Indizes zu erhalten. Dadurch können Sie alle Empfehlungen zu fehlenden Indizes für eine Datenbank anzeigen.

Anzeigen von Vorschlägen zu fehlenden Indizes in Ausführungsplänen

Abfrageausführungspläne können auf verschiedene Weise generiert oder bezogen werden:

Beispielsweise können Sie die folgende Abfrage verwenden, um Anforderungen für fehlende Indizes für die AdventureWorks-Beispieldatenbank zu generieren.

SELECT City, StateProvinceID, PostalCode  
FROM Person.Address as a
JOIN Person.BusinessEntityAddress as ba on
    a.AddressID = ba.AddressID
JOIN Person.Person as  p on
    ba.BusinessEntityID = p.BusinessEntityID
WHERE p.FirstName like 'K%' and
    StateProvinceID = 9;  
GO 

So generieren Sie die Anforderungen für fehlende Indizes und zeigen sie an:

  1. Öffnen Sie SSMS, und verbinden Sie eine Sitzung mit Ihrer Kopie der AdventureWorks-Beispieldatenbank.

  2. Fügen Sie die Abfrage in die Sitzung ein, und generieren Sie in SSMS einen geschätzten Ausführungsplan für die Abfrage, indem Sie die Symbolleistenschaltfläche Geschätzten Ausführungsplan anzeigen auswählen. Der Ausführungsplan wird in einem Bereich in der aktuellen Sitzung angezeigt. Am oberen Ende des Grafikplans wird eine grüne Anweisung Fehlender Index angezeigt.

    A graphic execution plan in SQL Server Management Studio. A missing index request appears at the top of the missing index request in green font, directly below the Transact-SQL statement.

    Ein einzelner Ausführungsplan kann mehrere fehlende Indexanforderungen enthalten, aber nur eine fehlende Indexanforderung kann im Grafikausführungsplan angezeigt werden. Eine Option zum Anzeigen einer vollständigen Liste der fehlenden Indizes für einen Ausführungsplan ist das Anzeigen des XML-Codes des Ausführungsplans.

  3. Klicken Sie mit der rechten Maustaste auf den Ausführungsplan, und wählen Sie im Menü Ausführungsplan-XML-Datei anzeigen... aus.

    Screenshot showing the menu that appears after right-clicking on an execution plan.

    Die XML-Datei des Ausführungsplans wird als neue Registerkarte innerhalb von SSMS geöffnet.

    Hinweis

    Unter der Menüoption Fehlende Indexdetails... wird nur ein einzelner Vorschlag für einen fehlenden Index angezeigt, selbst wenn in der XML-Datei des Ausführungsplans mehrere Vorschläge vorhanden sind. Der angezeigte fehlende Indexvorschlag ist möglicherweise nicht die mit der höchsten geschätzten Verbesserung für die Abfrage.

  4. Zeigen Sie mithilfe der Tastenkombination STRG+F das Dialogfeld Suchen an.

  5. Suchen Sie nach MissingIndex.

    Screenshot of the XML for an execution plan. The Find dialog has been opened, and the term MissingIndex has been searched for in the document.

    In diesem Beispiel gibt es zwei MissingIndex-Elemente.

    • Der erste Vorschlag für einen fehlenden Index empfiehlt, dass die Abfrage einen Index für die Person.Address-Tabelle verwendet, der eine Gleichheitssuche für die Spalte StateProvinceID unterstützt, die zwei weitere Spalten einbezieht, City und PostalCode. Zum Zeitpunkt der Optimierung war der Abfrageoptimierer der Ansicht, dass dieser Index die geschätzten Kosten der Abfrage um 34,2737 % reduzieren könnte.
    • Der zweite Vorschlag für einen fehlenden Index empfiehlt, dass die Abfrage einen Index für die Tabelle Person.Person verwendet, der eine Ungleichheitssuche für die FirstName-Spalte unterstützt. Zum Zeitpunkt der Optimierung war der Abfrageoptimierer der Ansicht, dass dieser Index die geschätzten Kosten der Abfrage um 18,1102 % reduzieren könnte.

Jeder datenträgerbasierte, nicht gruppierte Index in Ihrer Datenbank beansprucht Speicherplatz, erhöht den Aufwand für Einfügungen, Updates und Löschvorgänge und erfordert möglicherweise Standard Tenance. Aus diesen Gründen ist es eine bewährte Methode, alle Anforderungen für fehlende Indizes für eine Tabelle und die vorhandenen Indizes für eine Tabelle vor dem Hinzufügen eines Indexes auf der Grundlage eines Abfrageausführungsplans zu überprüfen.

Anzeigen von Vorschlägen für fehlende Indizes in DMVs

Sie können Informationen zu fehlenden Indizes abrufen, indem Sie die in der folgenden Tabelle aufgeführten dynamischen Verwaltungsobjekte abfragen.

Dynamische Verwaltungssicht Zurückgegebene Informationen
sys.dm_db_missing_index_group_stats (Transact-SQL) Gibt Zusammenfassungsinformationen zu fehlenden Indexgruppen zurück, z. B. die Leistungsverbesserungen, die durch die Implementierung einer bestimmten Gruppe fehlender Indizes erzielt werden können.
sys.dm_db_missing_index_groups (Transact-SQL) Gibt Informationen zu einer bestimmten Gruppe fehlender Indizes zurück, z. B. den Gruppenbezeichner und die Bezeichner aller fehlenden Indizes, die in dieser Gruppe enthalten sind.
sys.dm_db_missing_index_details (Transact-SQL) Gibt detaillierte Informationen zu einem fehlenden Index zurück; Sie gibt z. B. den Namen und den Bezeichner der Tabelle zurück, in der der Index fehlt, sowie die Spalten und Spaltentypen, aus denen der fehlende Index bestehen soll.
sys.dm_db_missing_index_columns (Transact-SQL) Gibt Informationen zu den Datenbanktabellenspalten zurück, bei denen ein Index fehlt.

Die folgende Abfrage verwendet die DMVs zu den fehlenden Indizes, um CREATE INDEX-Anweisungen zu generieren. Die hier gezeigten Anweisungen zur Indexerstellung sollen Sie bei der Erstellung Ihrer eigenen DDL unterstützen, nachdem Sie alle Anforderungen für die Tabelle zusammen mit vorhandenen Indizes für die Tabelle untersucht haben.

SELECT TOP 20
    CONVERT (varchar(30), getdate(), 126) AS runtime,
    CONVERT (decimal (28, 1), 
        migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) 
        ) AS estimated_improvement,
    'CREATE INDEX missing_index_' + 
        CONVERT (varchar, mig.index_group_handle) + '_' + 
        CONVERT (varchar, mid.index_handle) + ' ON ' + 
        mid.statement + ' (' + ISNULL (mid.equality_columns, '') + 
        CASE
            WHEN mid.equality_columns IS NOT NULL
            AND mid.inequality_columns IS NOT NULL THEN ','
            ELSE ''
        END + ISNULL (mid.inequality_columns, '') + ')' + 
        ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement
FROM sys.dm_db_missing_index_groups mig
JOIN sys.dm_db_missing_index_group_stats migs ON 
    migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid ON 
    mig.index_handle = mid.index_handle
ORDER BY estimated_improvement DESC;
GO

Diese Abfrage ordnet die Vorschläge nach einer Spalte mit dem Namen estimated_improvement. Die geschätzte Verbesserung basiert auf einer Kombination aus:

  • Den geschätzten Abfragekosten für Abfragen, die mit der Anforderung für den fehlenden Index verknüpft sind.
  • Den geschätzten Auswirkungen für das Hinzufügen des Indexes. Dies ist eine Schätzung, um wie viel der nicht gruppierte Index die Abfragekosten senken würde.
  • Die Summe der Ausführungen von Abfrageoperatoren (Suchvorgänge und Scans), die für Abfragen ausgeführt wurden, die der Anforderung für fehlende Indizes zugeordnet sind. Wie wir unter Beibehalten fehlender Indizes mit dem Abfragedatenspeicher erörtert haben, werden diese Informationen in regelmäßigen Abständen gelöscht.

Hinweis

Das Skript zur Indexerstellung in der Tiger Toolbox von Microsoft untersucht DMVs für fehlende Indizes und entfernt automatisch alle redundanten vorgeschlagenen Indizes, analysiert Indizes mit geringen Auswirkungen und generiert Skripts für die Indexerstellung für die Überprüfung durch Sie. Wie in der Abfrage oben werden KEINE Befehle zum Erstellen von Indizes ausgeführt. Das Skript für die Indexerstellung eignet sich für SQL Server und Azure SQL Managed Instance. Erwägen Sie für Azure SQL-Datenbank, die automatische Indexoptimierung zu implementieren.

Lesen Sie Einschränkungen der Funktion für fehlende Indizes, und erfahren Sie, wie Sie Vorschläge für fehlende Indizes anwenden, bevor Sie Indizes erstellen. Ändern Sie den Indexnamen ggf. so, dass er der Benennungskonvention für Ihre Datenbank entspricht.

Beibehalten fehlender Indizes mit dem Abfragedatenspeicher

Vorschläge zu fehlenden Indizes in DMVs werden durch Ereignisse wie Neustarts von Instanzen, Failover und das Offlineschalten einer Datenbank gelöscht. Ändern sich die Metadaten für eine Tabelle, werden darüber hinaus alle Informationen zu fehlenden Indizes für diese Tabelle aus den dynamischen Verwaltungsobjekten gelöscht. Tabellenmetadatenänderungen können auftreten, wenn Spalten aus einer Tabelle hinzugefügt oder gelöscht werden, z. B. wenn ein Index in einer Spalte einer Tabelle erstellt wird. Wenn Sie einen ALTER INDEX REBUILD-Vorgang für einen Index einer Tabelle ausführen, werden auch Anforderungen für fehlende Indizes für diese Tabelle gelöscht.

Ebenso werden Ausführungspläne, die im Plancache gespeichert sind, durch Ereignisse wie Neustarts von Instanzen, Failover und das Offlineschalten einer Datenbank gelöscht. Ausführungspläne können aufgrund des Speicherdrucks und der Neukompilierung aus dem Cache entfernt werden.

Vorschläge zu fehlenden Indizes in Ausführungsplänen können über diese Ereignisse hinweg beibehalten werden, wenn der Abfragedatenspeicher aktiviert wird.

Die folgende Abfrage ruft die ersten 20 Abfragepläne ab, die Anforderungen für fehlende Indizes aus dem Abfragespeicher enthalten, ausgehend von einer groben Schätzung der gesamten logischen Lesevorgänge für die Abfrage. Die Daten sind auf Abfrageausführungen innerhalb der letzten 48 Stunden beschränkt.

SELECT TOP 20
    qsq.query_id,
    SUM(qrs.count_executions) * AVG(qrs.avg_logical_io_reads) as est_logical_reads,
    SUM(qrs.count_executions) AS sum_executions,
    AVG(qrs.avg_logical_io_reads) AS avg_avg_logical_io_reads,
    SUM(qsq.count_compiles) AS sum_compiles,
    (SELECT TOP 1 qsqt.query_sql_text FROM sys.query_store_query_text qsqt
        WHERE qsqt.query_text_id = MAX(qsq.query_text_id)) AS query_text,    
    TRY_CONVERT(XML, (SELECT TOP 1 qsp2.query_plan from sys.query_store_plan qsp2
        WHERE qsp2.query_id=qsq.query_id
        ORDER BY qsp2.plan_id DESC)) AS query_plan
FROM sys.query_store_query qsq
JOIN sys.query_store_plan qsp on qsq.query_id=qsp.query_id
CROSS APPLY (SELECT TRY_CONVERT(XML, qsp.query_plan) AS query_plan_xml) AS qpx
JOIN sys.query_store_runtime_stats qrs on 
    qsp.plan_id = qrs.plan_id
JOIN sys.query_store_runtime_stats_interval qsrsi on 
    qrs.runtime_stats_interval_id=qsrsi.runtime_stats_interval_id
WHERE    
    qsp.query_plan like N'%<MissingIndexes>%'
    and qsrsi.start_time >= DATEADD(HH, -48, SYSDATETIME())
GROUP BY qsq.query_id, qsq.query_hash
ORDER BY est_logical_reads DESC;
GO

Anwenden von Vorschlägen zu fehlenden Indizes

Befolgen Sie die Entwurfsrichtlinien für nicht gruppierte Indizes, um Vorschläge für fehlende Indizes effektiv zu nutzen. Beim Optimieren von nicht gruppierten Indizes mit Vorschlägen für fehlende Indizes überprüfen Sie die Basistabellenstruktur, kombinieren Sie Indizes sorgfältig, berücksichtigen Sie die Reihenfolge der Schlüsselspalten, und überprüfen Sie die Vorschläge für enthaltene Spalten.

Überprüfen der Basistabellenstruktur

Bevor Sie nicht gruppierte Indizes für eine Tabelle auf der Grundlage von Vorschlägen für fehlende Indizes erstellen, überprüfen Sie den gruppierten Index der Tabelle.

Eine Möglichkeit zur Prüfung auf einen gruppierten Index ist die Verwendung der gespeicherten Systemprozedur sp_helpindex. Sie können beispielsweise eine Zusammenfassung der Indizes für die Tabelle Person.Address anzeigen, indem Sie die folgende Anweisung ausführen:

exec sp_helpindex 'Person.Address';
GO

Überprüfen Sie die Spalte index_description. Eine Tabelle kann nur über einen gruppierten Index verfügen. Wenn ein gruppierter Index für die Tabelle implementiert wurde, enthält index_description das Wort „clustered“.

Screenshot of the sp_helpindex being run against the `Person.Address` table in the AdventureWorks database. The table returns four indexes. The fourth index has an index_description that shows that it's a clustered, unique primary key.

Wenn kein gruppierter Index vorhanden ist, ist die Tabelle ein Heap. Überprüfen Sie in diesem Fall, ob die Tabelle absichtlich als Heap erstellt wurde, um ein bestimmtes Leistungsproblem zu lösen. Die meisten Tabellen profitieren von gruppierten Indizes: Oftmals werden Tabellen unabsichtlich als Heaps implementiert. Erwägen Sie die Implementierung eines gruppierten Indexes, ausgehend von den Entwurfsrichtlinien für gruppierte Indizes.

Überprüfen fehlender Indizes und vorhandener Indizes auf Überschneidungen

Fehlende Indizes können ähnliche Variationen von nicht gruppierten Indizes für dieselbe Tabelle und Spalte in Abfragen bieten. Fehlende Indizes können auch mit vorhandenen Indizes in einer Tabelle vergleichbar sein. Zum Erzielen einer optimalen Leistung sollten fehlende Indizes und vorhandene Indizes auf Überschneidungen untersucht und das Erstellen doppelter Indizes vermieden werden.

Erstellen eines Skripts für vorhandene Indizes für eine Tabelle

Eine Möglichkeit, die Definition vorhandener Indizes für eine Tabelle zu untersuchen, besteht im Erstellen eines Skripts für die Indizes mit Objekt-Explorer-Details:

  1. Stellen Sie eine Verbindung von Objekt-Explorer mit Ihrer Instanz oder Datenbank her.
  2. Erweitern Sie den Knoten für die in Frage stehende Datenbank im Objekt-Explorer.
  3. Erweitern Sie den Ordner Tabellen .
  4. Erweitern Sie die Tabelle, für die Sie Skripts für Indizes erstellen möchten.
  5. Wählen Sie den Ordner Indizes aus.
  6. Wenn der Detailbereich von Objekt-Explorer noch nicht geöffnet ist, wählen Sie im Menü AnsichtObjekt-Explorer-Details aus, oder drücken Sie F7.
  7. Wählen Sie alle im Bereich „Details“ von Objekt-Explorer aufgelisteten Indizes mit der Tastenkombination STRG+a aus.
  8. Klicken Sie mit der rechten Maustaste auf eine beliebige Stelle in der ausgewählten Region, und wählen Sie die Menüoption Script index as (Skript für Index erstellen als), dann CREATE To (Erstellen in) und Neues Abfrage-Editor-Fenster aus.

Screenshot of scripting out all indexes on a table using the Object Explorer Details pane in SSMS.

Überprüfen von Indizes und Kombinieren nach Möglichkeit

Überprüfen Sie die Empfehlungen für fehlende Indizes für eine Tabelle als Gruppe sowie die Definitionen vorhandener Indizes für die Tabelle. Denken Sie daran, dass beim Definieren von Indizes im Allgemeinen Gleichheitsspalten vor Ungleichheitsspalten platziert werden und sie zusammen den Schlüssel des Indexes bilden sollten. Für eine effektive Reihenfolge der Gleichheitsspalten sortieren Sie sie nach ihrer Selektivität, wobei Sie die ausgewählten Spalten zuerst (am weitesten links in der Spaltenliste) aufführen. Eindeutige Spalten sind am stärksten selektiv, während Spalten mit vielen sich wiederholenden Werten weniger selektiv sind.

Eingeschlossene Spalten sollten der CREATE INDEX-Anweisung mithilfe der INCLUDE-Klausel hinzugefügt werden. Die Reihenfolge der einbezogenen Spalten wirkt sich nicht auf die Abfrageleistung aus. Daher können bei der Kombination von Indizes eingeschlossene Spalten kombiniert werden, ohne sich gedanken über die Reihenfolge zu machen. Mehr dazu erfahren Sie unter Richtlinien für einbezogene Spalten.

Sie können z. B. eine Tabelle Person.Addressmit einem vorhandenen Index in der Schlüsselspalte haben StateProvinceID. Möglicherweise werden fehlende Indexempfehlungen für die Tabelle für die Person.Address folgenden Spalten angezeigt:

  • EQUALITY-Filter für StateProvinceID und City
  • EQUALITY-Filter für StateProvinceID und City, INCLUDE PostalCode

Wenn Sie den vorhandenen Index so ändern, dass er der zweiten Empfehlung entspricht, würde ein Index mit Schlüsseln für StateProvinceID und City, der PostalCode einbezieht, wahrscheinlich den Abfragen entsprechen, die beide Indexvorschläge generiert haben.

Kompromisse sind häufig bei der Indexoptimierung. Es ist wahrscheinlich, dass die Spalte City für viele Datasets stärker selektiv ist als die Spalte StateProvinceID. Wenn jedoch unser vorhandener Index für StateProvinceID stark verwendet wird und andere Anforderungen größtenteils sowohl nach StateProvinceID als auch City suchen, bedeutet es für die Datenbank im Allgemeinen weniger Mehraufwand, einen einzelnen Index mit beiden Spalten im Schlüssel zu verwenden, was zu StateProvinceID führt, obwohl dies nicht die am stärksten selektive Spalte ist.

Indizes können auf mehrere Arten geändert werden:

Die Reihenfolge der Indexschlüssel spielt beim Kombinieren der Indexvorschläge eine Rolle: City als führende Spalte unterscheidet sich von StateProvinceID als führender Spalte. Mehr dazu erfahren Sie unter Entwurfsrichtlinien für nicht gruppierte Indizes.

Erwägen Sie beim Erstellen von Indizes die Verwendung von Onlineindexvorgängen, wenn sie verfügbar sind.

Zwar können Indizes in einigen Fällen die Abfrageleistung erheblich verbessern, Indizes verursachen jedoch auch Mehraufwand und Verwaltungskosten. Lesen Sie die allgemeinen Richtlinien für den Indexentwurf, um den Nutzen von Indizes zu bewerten, bevor Sie sie erstellen.

Überprüfen, ob die Indexänderung erfolgreich war

Es ist wichtig zu überprüfen, ob Ihre Indexänderungen erfolgreich waren: Verwendet der Abfrageoptimierer Ihre Indizes?

Eine Möglichkeit, Ihre Indexänderungen zu überprüfen, besteht in der Verwendung des Abfragedatenspeichers, um Abfragen mit Anforderungen für fehlende Indizes zu identifizieren. Beachten Sie die query_id für die Abfragen. Verwenden Sie die Ansicht „Nachverfolgte Abfragen“ im Abfragedatenspeicher, um zu überprüfen, ob sich die Ausführungspläne für eine Abfrage geändert haben und ob der Optimierer Ihren neuen oder geänderten Index verwendet. Weitere Informationen zu nachverfolgten Abfragen finden Sie unter Erste Schritte bei der Behandlung von Problemen mit der Abfrageleistung.

Mehr zur Index- und Leistungsoptimierung erfahren Sie in den folgenden Artikeln: