Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Отменете оптимизатора на заявки за вашите T-SQL присъединявания с FORCEPLAN

SET FORCEPLAN изразът отменя логиката, използвана от оптимизатора на заявки на SQL Server за обработка на T-SQL SELECT изявление.

По-конкретно, когато FORCEPLAN е настроен на ON , оптимизаторът на заявки обработва присъединяване в същия ред, в който таблиците се появяват в FROM клауза на заявка.

Това също така налага използването на вложено свързване на цикъл, освен ако не са необходими други типове обединения за конструиране на план за заявката или те са поискани с намеци за присъединяване или намеци за заявка.

Пример

За да демонстрирате как FORCEPLAN работи, ще стартирам две SELECT заявки, първо с FORCEPLAN зададен на ON , след това с FORCEPLAN зададено на OFF .

И двете заявки са идентични, с изключение на това, че таблиците за свързване са в различен ред.

В този пример използвам SHOWPLAN_XML за да покажете прогнозния план за заявка, но можете също толкова лесно да използвате друг метод (като бутона Explain в Azure Data Studio или Include Actual Execution Plan икона в SSMS за показване на действителния план на заявката).

ЗАДАДЕТЕ FORCEPLAN ON

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;

Резултат:

Можем да видим, че планът на заявката за всяка заявка отразява реда, в който включих имената на таблиците в FROM клауза.

ИЗКЛЮЧЕТЕ 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;

Резултат:

Този път и двете заявки водят до идентичен план за заявка. Оптимизаторът на заявки игнорира реда, в който ги изброих в FROM клауза и определя своя собствен ред.

Имайте предвид, че FORCEPLAN настройката не променя данните, върнати от SELECT изявление. Реалните резултати са едни и същи, независимо дали FORCEPLAN е настроен на ON или OFF . Единствената разлика е начинът, по който се обработват таблиците (което може да повлияе на производителността).

Можете да използвате SET FORCEPLAN във връзка със съвети за оптимизатор на заявки, за да повлияе допълнително как се обработва заявката.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Премахнете SCHEMABINDING от изглед в SQL Server

  2. Как да предадете параметрите на стойността на таблицата към съхранената процедура от .net код

  3. Кога да използвате клъстерни или неклъстерни индекси в SQL Server

  4. Как да върна произволни числа като колона в SQL Server 2005?

  5. Предотвратяване на SQL инжектиране в ASP.Net