In che modo le compilazioni SQL influiscono sulle prestazioni di SQL Server?


20

Sto profilando un'istanza di un SQL Server 2005 e, tramite la SQLServer:SQL Statistics - SQL Compilations/secmetrica di PerfMon , vedo che la media è di circa 170 circa.

Ho creato SQL Profiler e ho cercato gli eventi SP: Compile o SQL: Compile. Apparentemente non esistono. Ho trovato Stored Procedure/SP:Recompileed TSQL/SQL:StmtRecompileeventi. La quantità di dati che vedo nel Profiler suggerisce che questi sono gli eventi sbagliati da guardare, anche se non sono sicuro.

Quindi le mie domande. Le risposte a qualcuno di questi sarebbero grandi.

  1. Come posso vedere cosa sta esattamente compilando in SQL Server?
  2. Ho scelto le metriche sbagliate da guardare? In Perfmon o SQL Profiler?
  3. Per quanto riguarda Stored Procedure/SP:Recompileed TSQL/SQL:StmtRecompileeventi in SQL Profiler ... non includono la metrica Duration. Come posso valutare l'impatto di questi eventi sul sistema se non forniscono alcun modo per vedere l'impatto dei tempi sul sistema.

Risposte:


33

Compilazioni SQL / sec è una buona metrica, ma solo se abbinato a Richieste batch / sec . Di per sé, le compilation al secondo non ti dicono molto.

Stai vedendo 170. Se il req in batch al secondo è solo 200 (un po 'esagerato per effetto), allora sì, è necessario arrivare al fondo della causa (molto probabilmente un uso eccessivo di query ad hoc e piani monouso). Ma se il tuo batch req al secondo misura circa 5000, 170 compilazioni al secondo non sono affatto male. È una regola empirica generale che le compilazioni / sec dovrebbero essere al 10% o inferiori alle richieste batch totali / sec .

Se vuoi davvero approfondire ciò che viene memorizzato nella cache, esegui la seguente query che utilizza i DMV appropriati:

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

Per ottenere tutti i piani monouso (un conteggio):

;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

Per ottenere un rapporto di quanti piani di conteggio monouso hai confrontato con tutti i piani memorizzati nella cache:

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

Per quanto riguarda le durate acquisite tramite una traccia di SQL Server, non è disponibile per gli eventi Ricompila. Non è così significativo vedere la durata o il dolore che sta causando la compilazione del piano, poiché non c'è molto che puoi fare per una situazione caso per caso. La soluzione è tentare di limitare le compilazioni e le ricompilazioni mediante il riutilizzo del piano (query con parametri, procedure memorizzate, ecc.).


9

Esistono tre contatori pertinenti che devono essere registrati utilizzando PerfMon (o un'altra soluzione di terze parti). Il punto chiave è in qualche modo registrare queste statistiche.

  • Statistiche SQL \ Richieste batch / sec
  • Statistiche SQL \ Compilazioni SQL / sec
  • Statistiche SQL \ Ricompilazioni SQL / sec

Come ha detto Thomas Stringer , è bene tenere d'occhio il rapporto tra compilazioni / richieste batch. Ovviamente, inferiore è meglio, ma ci sono solo linee guida per ciò che è "buono" e solo tu puoi decidere cosa è accettabile. La quantità assoluta di guadagno perf che vedrai riducendo il numero di compilation dipende da molti fattori.

Mi piace anche esaminare il rapporto ricompilazioni / compilazioni , per avere un'idea della quantità di riutilizzo del piano di query. Ancora una volta, abbassare è meglio. In questo caso, tuttavia, si desidera che si verifichino ricompilazioni nel sistema quando le statistiche cambiano (se il DB è di sola lettura e si hanno ricompilazioni ... qualcosa potrebbe non andare). Come ho detto prima, ci sono solo linee guida per ciò che è "buono".

Quello che vuoi davvero fare è tendenza questi numeri nel tempo, quindi se vedi un picco enorme in uno dei rapporti, qualcosa viene distribuito che non utilizza correttamente i piani di query (idealmente, questo viene catturato durante il test) - usa Shark's query di analisi per trovare i colpevoli. Inoltre, eccone uno per trovare query ricompilate frequentemente:

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

Se stai anche registrando le statistiche per l'utilizzo della CPU, tutte le statistiche possono essere correlate tra loro per scoprire quanto fa male e quanto aiutano le tue correzioni. In pratica, ho scoperto che anche solo una singola strategia del piano di query non valida su uno sproc core può mettere in ginocchio un server; ovviamente YMMV.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.