Szacowany w porównaniu do faktycznego planu zapytań z wywołaniami funkcji


11

Mam to zapytanie na serwerze SQL, zapytanie replikacji scalającej:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

Szacowany plan zapytań zawiera informacje o 3 zapytaniach:

  1. Powyższe zapytanie
  2. Wywołanie funkcji do fn_MSgeneration_downloadonly
  3. Wywołanie funkcji do fn_MSArticle_has_downloadonly_property

Rzeczywisty plan zapytań zawiera tylko te informacje:

  1. Powyższe zapytanie

Nic o funkcjach. Dlaczego w aktualnym planie brakuje informacji o funkcji?

Próbowałem tych opcji:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

Który stworzył rzeczywisty plan, ale brakowało części 2 i 3 takich samych, jak wtedy, gdy użyłem opcji rzeczywistego planu zapytań w Management Studio.

Jeśli na przykład miałbym użyć programu Profiler do przechwytywania informacji o wywołaniach funkcji, jakie zdarzenia wybrałbym?


Nie znalazłem odpowiedzi konkretnie związanej z planami zapytań, ale profilowałem SP: StmtStarting i SP: StmtCompleted i pokazywałem wywołania funkcji.

Odpowiedzi:


17

I nic o funkcjach. Dlaczego w aktualnym planie brakuje informacji o funkcji?

Jest to zgodne z projektem, ze względu na wydajność.

Funkcje zawierające BEGINiw ENDdefinicji tworzą nową ramkę stosu T-SQL dla każdego wiersza wejściowego. Innymi słowy, treść funkcji jest wykonywana osobno dla każdego wiersza wejściowego . Ten pojedynczy fakt wyjaśnia większość problemów związanych z wydajnością związanych ze skalarnymi funkcjami T-SQL i funkcjami składającymi się z wielu instrukcji (należy zauważyć, że wbudowane funkcje cenione w tabeli nie używają BEGIN...ENDskładni).

W kontekście twojego pytania spowodowałoby to pełne SHOWPLANwyjście dla każdego wiersza. Dane wyjściowe planu XML są dość szczegółowe i kosztowne w produkcji, więc generowanie pełnego wyniku dla każdego wiersza byłoby złym pomysłem.

Przykład

Rozważ poniższą funkcję skalarną T-SQL, utworzoną w przykładowej bazie danych AdventureWorks , która zwraca nazwę produktu na podstawie jego identyfikatora:

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

Plan przedrealizacyjny

Plan wstępnego wykonania (plan szacowany w SSMS) pokazuje informacje o planie dla instrukcji nadrzędnej i zagnieżdżonych wywołań funkcji:

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

Wyjście SSMS:

Plan wstępnego wykonania SSMS

Ten sam kod XML wyświetlany w Eksploratorze planów SQL Sentry wyraźnie pokazuje zagnieżdżoną naturę wywołań:

Plan wstępnej realizacji PE

Wyjście po wykonaniu

SSMS pokazuje szczegóły tylko dla głównego zapytania, gdy wymagane jest wyjście planu po wykonaniu:

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

Po wykonaniu SSMS

Wpływ działania na działanie w inny sposób można pokazać za pomocą klasy zdarzeń Showplan XML Statistics Profile w SQL Server Profiler, używając zapytania, które wywołuje funkcję wiele razy (raz na wiersz wejściowy):

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

Dane wyjściowe profilera:

Wyjście śledzenia

Istnieje pięć osobnych planów po wykonaniu dla wykonywania funkcji i jeden dla zapytania nadrzędnego. Pięć planów funkcji wygląda tak w dolnym okienku profilera:

Plany funkcji

Nadrzędny plan zapytań to:

Plan nadrzędny

Wykonanie zapytania bez TOP (5)klauzuli skutkuje pełnym planem wykonania dla każdego z 504 wierszy w tabeli Produkt. Prawdopodobnie zobaczysz, jak to szybko wymknie się spod kontroli przy większych stołach.

Sytuacja wyzwalaczy jest odwrotna. Nie zawierają one żadnych informacji o planie przed wykonaniem, ale zawierają plan po wykonaniu. Odzwierciedla to charakter wyzwalaczy oparty na zestawie; każdy jest uruchamiany raz dla wszystkich wierszy, których dotyczy problem, a nie raz dla każdego wiersza.


@PaulWhite czy istnieje jakiś dobry powód, dla którego plany wyzwalające nie są wyświetlane podczas żądania szacunkowego planu wykonania? To wydaje się użyteczną brakującą funkcją. Mogę dla tego utworzyć element Connect.
— usr

@usr - Może dlatego, że faktyczny wybrany buforowany plan może się różnić w zależności od faktycznej liczby wierszy, jak opisano tutaj? technet.microsoft.com/en-us/library/…
— Martin Smith

@MartinSmith może to być powód. Ostatnio element połączenia dla planów wykonania ograniczeń sprawdzania i fk został oznaczony jako ukończony, więc miałem nadzieję, że zrobią to samo z wyzwalaczami.
— usr

@usr - Ten tutaj ? 3 miesiące? To musi być rekordowy zwrot dla nowej prośby o nową funkcję!
— Martin Smith,

@MartinSmith tak, tamto. Zostało to „naprawione” 1-2 lata temu. Naprawdę mam nadzieję, że nie muszę przesyłać zapytań do magazynu zapytań. Miałem nadzieję, że kliknę przycisk w SSMS. Tak naprawdę byłem zaskoczony, widząc jakąkolwiek zmianę w części silnika, która nie była dotykana przez lata. Ale może nie było.
— usr
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.