Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Sovrascrivi Query Optimizer per i tuoi join T-SQL con FORCEPLAN

Il SET FORCEPLAN sovrascrive la logica utilizzata da Query Optimizer di SQL Server per elaborare un SELECT T-SQL dichiarazione.

Più precisamente, quando FORCEPLAN è impostato su ON , Query Optimizer elabora un join nello stesso ordine in cui le tabelle appaiono in FROM clausola di una query.

Ciò impone anche l'uso di un join di ciclo nidificato a meno che non siano necessari altri tipi di join per costruire un piano per la query, o siano richiesti con suggerimenti di join o suggerimenti per la query.

Esempio

Per dimostrare come FORCEPLAN funziona, eseguirò due SELECT query, prima con FORCEPLAN impostato su ON , quindi con FORCEPLAN impostato su OFF .

Entrambe le query sono identiche, con l'eccezione che le tabelle di join sono elencate in un ordine diverso.

In questo esempio utilizzo SHOWPLAN_XML per mostrare il piano di query stimato, ma puoi usare altrettanto facilmente un altro metodo (come il pulsante Spiega in Azure Data Studio o il Include Actual Execution Plan icona in SSMS per visualizzare il piano di query effettivo).

ATTIVARE FORCEPLAN

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;

Risultato:

Possiamo vedere che il piano di query per ciascuna query riflette l'ordine in cui ho incluso i nomi delle tabelle nel FROM clausola.

DISATTIVARE FORCEPLAN

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;

Risultato:

Questa volta, entrambe le query risultano in un piano di query identico. Query Optimizer ha ignorato l'ordine in cui li ho elencati in FROM clausola e determinato il proprio ordine.

Nota che il FORCEPLAN l'impostazione non modifica i dati restituiti da SELECT dichiarazione. I risultati effettivi sono gli stessi indipendentemente dal fatto che FORCEPLAN è impostato su ON o OFF . L'unica differenza è il modo in cui vengono elaborate le tabelle (che potrebbe influire sulle prestazioni).

Puoi usare SET FORCEPLAN insieme ai suggerimenti di Query Optimizer per influenzare ulteriormente il modo in cui viene elaborata la query.