Les compilations SQL / s sont une bonne métrique, mais uniquement lorsqu'elles sont couplées avec des demandes par lots / s . En soi, les compilations par seconde ne vous disent pas grand-chose.
Vous voyez 170. Si la demande par lot par seconde n'est que de 200 (un peu exagéré pour l'effet), alors oui, vous devez aller au fond de la cause (très probablement une surutilisation des requêtes ad hoc et des plans à usage unique). Mais si votre demande de lot par seconde mesure environ 5000, 170 compilations par seconde ne sont pas mauvaises du tout. C'est une règle générale que les compilations / sec doivent être à 10% ou moins que le total des demandes de lot / sec .
Si vous voulez vraiment explorer ce qui est mis en cache, exécutez la requête suivante qui utilise les DMV appropriés:
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
Pour obtenir tous les plans à usage unique (un décompte):
;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
Pour obtenir un ratio du nombre de plans de comptage à usage unique que vous avez comparés à tous les plans mis en 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
Quant aux durées capturées via une trace SQL Server, elles ne sont pas disponibles pour les événements de recompilation. Il n'est pas si important de voir la durée ou la douleur que la compilation du plan provoque, car il n'y a pas grand-chose que vous pouvez faire pour une situation au cas par cas. La solution consiste à tenter de limiter les compilations et recompilations par la réutilisation des plans (requêtes paramétrées, procédures stockées, etc.).