Jak bardzo kompilacje SQL wpływają na wydajność programu SQL Server?

20

Profiluję wystąpienie programu SQL Server 2005 i za pomocą SQLServer:SQL Statistics - SQL Compilations/secmetryki PerfMon widzę, że średnia wynosi około 170.

Wyciągnąłem SQL Profiler i szukałem zdarzeń SP: Compile lub SQL: Compile. Najwyraźniej nie istnieją. ZnalazłemStored Procedure/SP:Recompile i TSQL/SQL:StmtRecompilewydarzenia. Ilość danych, które widzę w Profiler, sugeruje, że są to niewłaściwe zdarzenia, na które należy patrzeć, chociaż nie jestem pewien.

Więc moje pytania. Odpowiedzi na którekolwiek z nich byłyby świetne.

  1. Jak mogę zobaczyć, co dokładnie kompiluje się w SQL Server?
  2. Czy wybrałem niewłaściwe dane do obejrzenia? W Perfmon lub SQL Profiler?
  3. W odniesieniu do Stored Procedure/SP:Recompilei TSQL/SQL:StmtRecompilezdarzeń w SQL Profiler ... nie zawierają pomiaru czasu trwania. Jak mogę zmierzyć wpływ tych zdarzeń na system, jeśli nie dają one żadnego sposobu, aby zobaczyć wpływ czasu na system.
AngryHacker
źródło

Odpowiedzi:

33

Kompilacje SQL / s to dobra miara, ale tylko w połączeniu z żądaniami wsadowymi / s . Same kompilacje na sekundę tak naprawdę niewiele mówią.

Widzisz 170. Jeśli zapotrzebowanie na partię na sekundę wynosi tylko 200 (nieco przesadzone ze względu na efekt), to tak, musisz przejść do sedna przyczyny (najprawdopodobniej nadużywanie zapytań ad hoc i planów jednorazowego użytku). Ale jeśli twoje zapotrzebowanie na partię wynosi około 5000, to 170 kompilacji na sekundę wcale nie jest złe. Ogólna zasada jest taka, że ​​liczba kompilacji na sekundę powinna wynosić 10% lub mniej niż łączna liczba żądań partii na sekundę .

Jeśli naprawdę chcesz dokładnie zbadać, co jest buforowane, uruchom następujące zapytanie, które wykorzystuje odpowiednie DMV:

select
    db_name(st.dbid) as database_name,
    cp.bucketid,
    cp.usecounts,
    cp.size_in_bytes,
    cp.objtype,
    st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st

Aby uzyskać wszystkie plany jednorazowego użytku (liczba):

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
)
select count(*)
from PlanCacheCte
where usecounts = 1

Aby uzyskać stosunek liczby planów jednorazowego użytku do wszystkich planów buforowanych:

declare @single_use_counts int, @multi_use_counts int

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @single_use_counts = count(*)
from PlanCacheCte
where usecounts = 1

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @multi_use_counts = count(*)
from PlanCacheCte
where usecounts > 1

select
    @single_use_counts as single_use_counts,
    @multi_use_counts as multi_use_counts,
    @single_use_counts * 1.0 / (@single_use_counts + @multi_use_counts) * 100
        as percent_single_use_counts

Jeśli chodzi o czasy trwania przechwycone przez śledzenie programu SQL Server, nie jest ono dostępne dla zdarzeń ponownej kompilacji. Nie jest tak istotne, aby zobaczyć czas trwania lub ból, który powoduje kompilacja planu, ponieważ niewiele można zrobić w przypadku poszczególnych przypadków. Rozwiązaniem jest próba ograniczenia kompilacji i ponownych kompilacji poprzez ponowne użycie planu (sparametryzowane zapytania, procedury składowane itp.).

Thomas Stringer
źródło
9

Istnieją trzy odpowiednie liczniki, które należy zarejestrować za pomocą PerfMon (lub innego rozwiązania innej firmy). Najważniejsze jest, aby jakoś zapisać te statystyki.

  • Statystyka SQL \ Żądania wsadowe / s
  • Statystyka SQL \ Kompilacje SQL / s
  • Statystyka SQL \ Ponowne kompilacje SQL / s

Jak wspomniał Thomas Stringer , dobrze jest mieć oko na stosunek kompilacji / żądania wsadowego. Oczywiście niższe jest lepsze, ale istnieją tylko wytyczne dotyczące tego, co jest „dobre” i tylko Ty możesz zdecydować, co jest dopuszczalne. Bezwzględna wartość wzmocnienia, którą zobaczysz, zmniejszając liczbę kompilacji, zależy od wielu czynników.

Lubię też patrzeć na stosunek rekompilacji / kompilacji , aby dowiedzieć się o ilości ponownego użycia planu zapytań. Ponownie, niższe jest lepsze. Jednak w tym przypadku chcesz, aby rekompilacje zachodziły w systemie wraz ze zmianą statystyk (jeśli DB jest tylko do odczytu i rekompilujesz ... coś może być nie tak). Tak jak powiedziałem wcześniej, istnieją tylko wytyczne dotyczące tego, co jest „dobre”.

To, co naprawdę chcesz zrobić, to trendować te liczby w czasie, więc jeśli zobaczysz ogromny skok w którymkolwiek ze współczynników, oznacza to, że wdrożono coś, co nie używa poprawnie planów zapytań (najlepiej, że zostaje to złapane podczas testowania) - użyj Sharka analizy zapytań, aby znaleźć sprawców. Ponadto tutaj można znaleźć często rekompilowane zapytania:

SELECT TOP 50
    qs.plan_generation_num,
    qs.execution_count,
    qs.statement_start_offset,
    qs.statement_end_offset,
    st.text
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
    WHERE qs.plan_generation_num > 1
    ORDER BY qs.plan_generation_num DESC

Jeśli rejestrujesz również statystyki dotyczące użycia procesora, wszystkie statystyki można ze sobą skorelować, aby dowiedzieć się, jak bardzo boli i jak bardzo pomagają twoje poprawki. W praktyce odkryłem, że nawet pojedyncza strategia złych zapytań na rdzeń sproc może rzucić serwer na kolana; oczywiście YMMV.

Jon Seigel
źródło