Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Was sind die Hauptunterschiede zwischen OPTION(OPTIMIZE FOR UNKNOWN) und OPTION(RECOMPILE)?

Ja, das wird es.

Es gibt zwei Hauptunterschiede zwischen OPTION(OPTIMIZE FOR UNKNOWN) und OPTION(RECOMPILE) wie aus diesem Zitat von MSDN ersichtlich ist :

Die beiden Hauptunterschiede sind also:

  1. Caching (oder nicht) des Abfrageplans.

Normalerweise wird der generierte Abfrageplan zwischengespeichert und wiederverwendet. OPTIMIZE FOR UNKNOWN hat keinen Einfluss auf diese Funktion der Engine. RECOMPILE unterdrückt diese Funktion und weist die Engine an, den Plan zu verwerfen und nicht in den Cache zu legen.

  1. Verwenden (oder nicht) tatsächlicher Parameterwerte während der Planerstellung.

Normalerweise "schnüffelt" der Optimierer die Parameterwerte und verwendet diese Werte beim Generieren des Plans. OPTIMIZE FOR UNKNOWN unterdrückt diese Funktion und weist die Engine an, alle Parameter so zu behandeln, als ob ihre Werte unbekannt wären. Optimizer verfügt über integrierte Regeln und Heuristiken zur Verwendung verfügbarer Statistiken für verschiedene Filterkriterien. Siehe Optimieren für… Mittelmäßig? für mehr Details. Normalerweise wird Parameter Sniffing bei der ersten Ausführung der Abfrage/gespeicherten Prozedur verwendet und verwendet die Werte der Parameter während der ersten Ausführung. Der generierte Plan wird zwischengespeichert und kann später wiederverwendet werden.

Eine nicht offensichtliche Sache, an die Sie sich hier erinnern sollten, ist, dass in beiden Fällen (normal ohne Abfragehinweise und mit OPTIMIZE FOR UNKNOWN Hinweis) der generierte Plan muss gültig sein und für beliebige korrekte Ergebnisse liefern möglicher Parameterwert. Es ist auf die geschnüffelten Werte zugeschnitten, die während des ersten Durchlaufs im normalen/kein-Hinweis-Fall verwendet wurden; es ist nicht auf einen bestimmten Wert in OPTIMIZE FOR UNKNOWN zugeschnitten Fall, aber es ist immer noch gültig, wenn sich der Parameter später in irgendeiner Weise ändert.

Dies ist erheblich und verhindert, dass der Optimierer bestimmte Transformationen und Vereinfachungen des Plans durchführt.

OPTION(RECOMPILE) ermöglicht dem Optimierer, die tatsächlichen Werte der Parameter während jedes Laufs einzufügen, und der Optimierer verwendet die tatsächlichen Werte der Parameter, um einen besseren Plan zu erstellen. Es muss nicht befürchtet werden, dass der generierte Plan mit einem anderen Parameterwert nicht funktioniert, da der Plan nicht zwischengespeichert und wiederverwendet wird.

Dieser Effekt ist vor allem bei den dynamischen Suchbedingungen sichtbar Abfragen. Zum Beispiel:

SELECT ...
FROM T
WHERE
    (@ParamSomeID = 0)
    OR
    (
        @ParamSomeID = -1
        AND
        T.SomeID NOT IN
        (
            SELECT OtherTable.SomeID
            FROM OtherTable
        )
    )
    OR
    (
        T.SomeID IN
        (
            SELECT OtherTable.SomeID
            FROM OtherTable
            WHERE OtherTable.SomeID = @ParamSomeID
        )
    )
OPTION(RECOMPILE)

Wenn @ParamSomeID ist 0 Der Optimierer würde die Abfrage so behandeln, als hätte sie kein WHERE Klausel überhaupt. Der Plan würde OtherTable nicht erwähnen überhaupt.

Wenn @ParamSomeID ist -1 , würde der Plan T beitreten zu OtherTable mit Left Anti Semi Join und würde die gesamte OtherTable scannen .

Wenn @ParamSomeID beispielsweise 5 ist, würde der Plan eine Indexsuche im eindeutigen Index auf OtherTable durchführen und lese nur eine Zeile aus OtherTable .

Ohne OPTION(RECOMPILE) diese Art von Vereinfachung und Transformation würde nicht stattfinden.

Ein weiterer Grund, OPTION(RECOMPILE) zu verwenden ist, wenn Ihre Datenverteilung sehr verzerrt ist. Sie haben beispielsweise eine Tabelle mit 1 Mio. Zeilen. Eine Spalte hat den Wert 0 in 990.000 Zeilen und Werte von 1 bis 10 in 1.000 Zeilen. Die Abfragen, die nach dieser Spalte filtern, sollten abhängig vom tatsächlichen Wert des Filters unterschiedliche Pläne haben.

In beiden obigen Beispielen OPTIMIZE FOR UNKNOWN würde einen mittelmäßigen Plan generieren.