it-swarm-eu.dev

Jak špatně ovlivňují kompilace SQL výkon serveru SQL?

Profilovám instanci serveru SQL Server 2005 a pomocí metriky SQLServer:SQL Statistics - SQL Compilations/sec PerfMon vidím, že průměr je kolem 170.

Vyhodil jsem SQL Profiler a hledal jsem SP: Compile nebo SQL: Compile události. Očividně neexistují. Našel jsem Stored Procedure/SP:Recompile A TSQL/SQL:StmtRecompile Události. Množství údajů, které vidím v Profileru, naznačuje, že se jedná o nesprávné události, na které se musím podívat, i když si nejsem jistý.

Takže moje otázky. Odpovědi na cokoli z nich by byly skvělé.

  1. Jak vidím, co přesně se kompiluje na serveru SQL?
  2. Vybral jsem špatné metriky, na které bych se měl podívat? V Perfmon nebo SQL Profiler?
  3. Pokud jde o události Stored Procedure/SP:Recompile A TSQL/SQL:StmtRecompile V SQL Profiler ..., nezahrnují metriku Duration. Jak mohu měřit dopad těchto událostí na systém, pokud neposkytují žádný způsob, jak vidět dopad načasování na systém.
22
AngryHacker

Kompilace SQL/s je dobrá metrika, ale pouze ve spojení s Požadavky na dávku/s. Samotné kompilace za sekundu vám toho moc neřeknou.

Uvidíte 170. Pokud je dávka za sekundu pouze 200 (trochu přehnaná kvůli účinku), pak ano, musíte se dostat až na konec příčiny (s největší pravděpodobností nadužívání ad hoc dotazů a plány na jedno použití). Pokud však vaše dávka za sekundu měří asi 5000, pak 170 kompilací za sekundu není vůbec špatné. Obecným pravidlem je, že Kompilace/sec by mělo být na 10% nebo méně než celkem Žádosti o dávku/sec.

Pokud opravdu chcete provést podrobnou analýzu toho, co je v mezipaměti, spusťte následující dotaz, který využívá příslušné 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

Chcete-li získat všechny plány na jedno použití (počet):

;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

Chcete-li získat poměr počtu plánů pro jedno použití, které jste porovnali se všemi plány uloženými v mezipaměti:

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

Pokud jde o doby zachycené pomocí trasování SQL Server, není k dispozici pro události Recompile. Není tak důležité vidět trvání nebo bolest, které způsobuje kompilace plánu, protože pro případ od případu není moc co dělat. Řešením je pokusit se omezit kompilace a rekompilace opakovaným použitím plánu (parametrizované dotazy, uložené procedury atd.).

33
Thomas Stringer

Existují tři relevantní čítače, které by měly být zaznamenány pomocí PerfMon (nebo jiného řešení třetí strany). Klíčovým bodem je zaznamenání těchto statistik.

  • SQL Statistics\Batch Request/sec
  • SQL Statistics\SQL Compilations/sec
  • SQL Statistics\SQL Re-Compilations/sec

Jak zmínil se Thomas Stringer , je dobré dávat pozor na poměr kompilace/žádosti o dávku. Je zřejmé, že nižší je lepší, ale existují pouze pokyny pro to, co je „dobré“, a pouze vy můžete rozhodnout, co je přijatelné. Absolutní výše zisku perfu, kterou uvidíte snížením počtu kompilací, závisí na mnoha faktorech.

Také se rád podívám na poměr rekompilací/kompilace , abych získal představu o množství opakovaného použití plánu dotazů. Opět platí, že nižší je lepší. V tomto případě však chcete, aby se v systému objevovaly rekompily, jak se mění statistika (pokud je DB pouze pro čtení a máte rekompily ... něco může být špatně). Stejně jako jsem řekl dříve, existují pouze pokyny pro to, co je „dobré“.

To, co opravdu chcete udělat, je trend těchto čísel v průběhu času, takže pokud v některém z poměrů vidíte obrovský nárůst, došlo k něčemu, co správně nepoužívá plány dotazů (v ideálním případě se to během testování zachytí) - použijte Shark's analýza dotazů najít viníky. Dále je zde jeden, který najde často překompilované dotazy:

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

Pokud také zaznamenáváte statistiky využití CPU, mohou být všechny statistiky spolu korelovány, aby se zjistilo, jak moc to bolí a kolik vašich oprav pomůže. V praxi jsem zjistil, že i jediná špatná strategie plánu dotazů na jádro sproc může přinést server na kolena; očividně YMMV.

10
Jon Seigel