Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Remplacer l'optimiseur de requête pour vos jointures T-SQL avec FORCEPLAN

Le SET FORCEPLAN l'instruction remplace la logique utilisée par l'optimiseur de requête SQL Server pour traiter un SELECT T-SQL déclaration.

Plus précisément, lorsque FORCEPLAN est réglé sur ON , l'optimiseur de requête traite une jointure dans le même ordre que les tables apparaissent dans le FROM clause d'une requête.

Cela force également l'utilisation d'une jointure de boucle imbriquée à moins que d'autres types de jointures ne soient nécessaires pour construire un plan pour la requête, ou qu'elles soient demandées avec des conseils de jointure ou des conseils de requête.

Exemple

Pour démontrer comment FORCEPLAN fonctionne, je vais exécuter deux SELECT requêtes, d'abord avec FORCEPLAN réglé sur ON , puis avec FORCEPLAN réglé sur OFF .

Les deux requêtes sont identiques, à l'exception du fait que les tables de jointure sont répertoriées dans un ordre différent.

Dans cet exemple, j'utilise SHOWPLAN_XML pour afficher le plan de requête estimé, mais vous pouvez tout aussi facilement utiliser une autre méthode (telle que le bouton Expliquer dans Azure Data Studio ou le bouton Include Actual Execution Plan icône dans SSMS pour afficher le plan de requête réel).

ACTIVER 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;

Résultat :

Nous pouvons voir que le plan de requête pour chaque requête reflète l'ordre dans lequel j'ai inclus les noms de table dans le FROM clause.

DÉSACTIVER 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;

Résultat :

Cette fois, les deux requêtes aboutissent à un plan de requête identique. L'optimiseur de requête a ignoré l'ordre dans lequel je les ai répertoriés dans le FROM clause et a déterminé son propre ordre.

Notez que le FORCEPLAN paramètre ne modifie pas les données renvoyées par le SELECT déclaration. Les résultats réels sont les mêmes, que FORCEPLAN est réglé sur ON ou OFF . La seule différence est la manière dont les tables sont traitées (ce qui peut avoir un impact sur les performances).

Vous pouvez utiliser SET FORCEPLAN en conjonction avec les conseils de l'optimiseur de requête pour affecter davantage la façon dont la requête est traitée.