Problembehandlung bei schlechter Abfrageleistung: Schätzung der Kardinalität

Der Abfrageoptimierer von SQL Server ist kostenbasiert. Das bedeutet, dass er die Abfragepläne zur Ausführung auswählt, die die niedrigsten geschätzten Verarbeitungskosten aufweisen. Der Abfrageoptimierer bestimmt die Kosten für die Ausführung eines Abfrageplans anhand zweier Hauptfaktoren:

  • Die Gesamtanzahl der Zeilen, die auf den jeweiligen Stufen eines Abfrageplans verarbeitet werden. Wird als Kardinalität des Plans bezeichnet.

  • Das Kostenmodell des Algorithmus, der von den in der Abfrage verwendeten Operatoren vorgeschrieben wird.

Der erste Faktor, die Kardinalität, wird als Eingabeparameter für den zweiten Faktor, das Kostenmodell, verwendet. Aus diesem Grund führt eine verbesserte Kardinalität zu verbesserten geschätzten Kosten und wiederum zu schnelleren Ausführungsplänen.

SQL Server schätzt die Kardinalitätswerte in erster Linie mithilfe von Histogrammen, die erstellt werden, wenn Indizes oder Statistiken erstellt werden. Der Vorgang kann entweder manuell oder automatisch durchgeführt werden. In manchen Fällen verwendet SQL Server auch Einschränkungsinformationen und logische Umschreibungen von Abfragen, um die Kardinalität zu bestimmen.

In den folgenden Fällen kann SQL Server die Kardinalitätswerte nicht genau berechnen. Dies führt zu ungenauen Kostenberechnungen, die wiederum nicht optimale Abfragepläne zur Folge haben. Die Vermeidung dieser Konstrukte in Abfragen kann die Abfrageleistung verbessern. In manchen Fällen sind alternative Abfrageformulierungen oder andere Measures möglich, die dann angegeben sind.

  • Abfragen mit Prädikaten, die Vergleichsoperatoren zwischen verschiedenen Spalten derselben Tabelle verwenden.

  • Abfragen mit Prädikaten, die Operatoren verwenden, und für die eine der folgenden Voraussetzungen zutrifft:

    • Es liegen keine Statistiken zu den beteiligten Spalten auf beiden Seiten der Operatoren vor.

    • Die Verteilung der Werte in den Statistiken ist nicht einheitlich, die Abfrage sucht jedoch eine sehr gezielte Wertegruppe. Dieser Umstand tritt besonders dann ein, wenn ein anderer Operator als der equality-Operator (=) verwendet wird.

    • Das Prädikat verwendet den Ungleich-Vergleichsoperator (!=) oder den logischen Operator NOT.

  • Abfragen, die eine der integrierten SQL Server-Funktionen oder eine benutzerdefinierte Skalarwertfunktion verwenden, deren Argument kein konstanter Wert ist.

  • Abfragen, bei denen Spalten durch arithmetische Operatoren oder Zeichenfolgenverkettungsoperatoren verknüpft werden.

  • Abfragen, die Variablen vergleichen, deren Werte zum Zeitpunkt der Kompilierung oder Optimierung nicht bekannt sind.

Ergreifen Sie folgende Maßnahmen, um zu versuchen, die Leistung dieser Abfragetypen zu verbessern:

  • Erstellen Sie sinnvolle Indizes oder Statistiken für die Spalten, die von der Abfrage betroffen sind. Weitere Informationen finden Sie unter Entwerfen von Indizes und unter Verwenden von Statistiken zum Verbessern der Abfrageleistung.

  • Verwenden Sie berechnete Spalten, und schreiben Sie die Abfrage neu, falls die Abfrage Vergleichsoperatoren oder arithmetische Operatoren verwendet, um zwei oder mehrere Spalten zu vergleichen oder zu kombinieren. Folgende Abfrage vergleicht beispielsweise die Werte zweier Spalten:

    SELECT * FROM MyTable
    WHERE MyTable.Col1 > MyTable.Col2
    

    Die Leistung kann verbessert werden, wenn Sie der MyTable-Tabelle eine berechnete Col3-Spalte hinzufügen, die die Differenz zwischen Col1 und Col2 berechnet (Col1 minus Col2) . Schreiben Sie anschließend die Abfrage um:

    SELECT * FROM MyTable
    WHERE Col3 > 0
    

    Die Leistung wird wahrscheinlich noch weiter verbessert, wenn Sie einen Index für MyTable.Col3 erstellen.