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.