sql >> Databasteknik >  >> RDS >> Sqlserver

Åsidosätt frågeoptimeraren för dina T-SQL-anslutningar med FORCEPLAN

SET FORCEPLAN sats åsidosätter logiken som används av SQL Server-frågeoptimeraren för att bearbeta en T-SQL SELECT uttalande.

Mer specifikt när FORCEPLAN är inställd på ON , bearbetar frågeoptimeraren en join i samma ordning som tabellerna visas i FROM klausul i en fråga.

Detta tvingar också användningen av en kapslad loop-join såvida inte andra typer av joins krävs för att konstruera en plan för frågan, eller om de begärs med join-tips eller frågetips.

Exempel

För att visa hur FORCEPLAN fungerar, jag kommer att köra två SELECT frågor, först med FORCEPLAN inställd på ON , sedan med FORCEPLAN inställd på OFF .

Båda frågorna är identiska, med undantaget att kopplingstabellerna visas i en annan ordning.

I det här exemplet använder jag SHOWPLAN_XML för att visa den beräknade frågeplanen, men du kan lika gärna använda en annan metod (som knappen Förklara i Azure Data Studio eller Include Actual Execution Plan ikonen i SSMS för att visa den faktiska frågeplanen).

STÄLL PÅ 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;

Resultat:

Vi kan se att frågeplanen för varje fråga återspeglar den ordning i vilken jag inkluderade tabellnamnen i FROM klausul.

STÄLL AV 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;

Resultat:

Den här gången resulterar båda frågorna i en identisk frågeplan. Frågeoptimeraren ignorerade ordningen i vilken jag listade dem i FROM klausul och bestämde sin egen ordning.

Observera att FORCEPLAN inställningen ändrar inte data som returneras av SELECT påstående. De faktiska resultaten är desamma oavsett om FORCEPLAN är är inställd på ON eller OFF . Den enda skillnaden är det sätt på vilket tabeller bearbetas (vilket kan påverka prestanda).

Du kan använda SET FORCEPLAN i samband med frågeoptimerarens tips för att ytterligare påverka hur frågan bearbetas.


  1. Mysql select rekursiv få alla barn med flera nivåer

  2. Hur man inkluderar en PHP-variabel i en MySQL-sats

  3. Postgresql:Skriptkörning av psql med lösenord

  4. Hoppa till Start Testdriven Databas Development (TDDD)