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

Überschreiben Sie den Abfrageoptimierer für Ihre T-SQL-Joins mit FORCEPLAN

Der SET FORCEPLAN -Anweisung überschreibt die Logik, die vom SQL Server-Abfrageoptimierer zum Verarbeiten eines T-SQL-SELECT verwendet wird Aussage.

Genauer gesagt, wenn FORCEPLAN auf ON eingestellt ist , verarbeitet der Abfrageoptimierer einen Join in derselben Reihenfolge, in der die Tabellen in FROM erscheinen Klausel einer Abfrage.

Dies erzwingt auch die Verwendung eines Joins mit verschachtelten Schleifen, es sei denn, es sind andere Arten von Joins erforderlich, um einen Plan für die Abfrage zu erstellen, oder sie werden mit Join-Hinweisen oder Abfragehinweisen angefordert.

Beispiel

Um zu demonstrieren, wie FORCEPLAN funktioniert, werde ich zwei SELECT ausführen Abfragen, zuerst mit FORCEPLAN auf ON setzen , dann mit FORCEPLAN auf OFF stellen .

Beide Abfragen sind identisch, mit der Ausnahme, dass die Join-Tabellen in einer anderen Reihenfolge aufgeführt sind.

In diesem Beispiel verwende ich SHOWPLAN_XML um den geschätzten Abfrageplan anzuzeigen, aber Sie könnten genauso gut eine andere Methode verwenden (z. B. die Schaltfläche Erklären in Azure Data Studio oder Include Actual Execution Plan). Symbol in SSMS, um den tatsächlichen Abfrageplan anzuzeigen).

FORCEPLAN EINSTELLEN

SET FORCEPLAN ON;
GO

SET SHOWPLAN_XML ON;
GO

SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Artists ar 
    INNER JOIN Albums al 
    ON ar.ArtistId = al.ArtistId 
    INNER JOIN Genres g 
    ON al.GenreId = g.GenreId;

SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Albums al
    INNER JOIN Genres g 
    ON al.GenreId = g.GenreId
    INNER JOIN Artists ar 
    ON ar.ArtistId = al.ArtistId;

Ergebnis:

Wir können sehen, dass der Abfrageplan für jede Abfrage die Reihenfolge widerspiegelt, in der ich die Tabellennamen in FROM eingefügt habe Klausel.

FORCEPLAN AUSSCHALTEN

SET SHOWPLAN_XML OFF;
GO

SET FORCEPLAN OFF;
GO

SET SHOWPLAN_XML ON;
GO

SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Artists ar 
    INNER JOIN Albums al 
    ON ar.ArtistId = al.ArtistId 
    INNER JOIN Genres g 
    ON al.GenreId = g.GenreId;

SELECT
    ar.ArtistName,
    al.AlbumName,
    g.Genre
FROM 
    Albums al
    INNER JOIN Genres g 
    ON al.GenreId = g.GenreId
    INNER JOIN Artists ar 
    ON ar.ArtistId = al.ArtistId;

Ergebnis:

Diesmal führen beide Abfragen zu einem identischen Abfrageplan. Der Abfrageoptimierer ignorierte die Reihenfolge, in der ich sie im FROM aufgeführt habe Klausel und bestimmte seine eigene Reihenfolge.

Beachten Sie, dass der FORCEPLAN Die Einstellung ändert nicht die von SELECT zurückgegebenen Daten Erklärung. Die tatsächlichen Ergebnisse sind dieselben, unabhängig davon, ob FORCEPLAN auf ON eingestellt ist oder OFF . Der einzige Unterschied besteht in der Art und Weise, wie Tabellen verarbeitet werden (was sich auf die Leistung auswirken kann).

Sie können SET FORCEPLAN verwenden in Verbindung mit Hinweisen des Abfrageoptimierers, um die Verarbeitung der Abfrage weiter zu beeinflussen.