Dans quelle mesure les compilations SQL ont-elles un impact sur les performances de SQL Server?


20

Je suis en train de profiler une instance d'un SQL Server 2005 et moi, via la SQLServer:SQL Statistics - SQL Compilations/secmétrique de PerfMon, je vois que la moyenne est d'environ 170 ou plus.

J'ai supprimé SQL Profiler et recherché les événements SP: Compile ou SQL: Compile. Apparemment, ils n'existent pas. J'ai trouvé Stored Procedure/SP:Recompileet des TSQL/SQL:StmtRecompileévénements. La quantité de données que je vois dans le profileur suggère que ce sont les mauvais événements à regarder, bien que je ne sois pas sûr.

Alors mes questions. Des réponses à ces questions seraient formidables.

  1. Comment puis-je voir ce qui se compile exactement dans SQL Server?
  2. Ai-je choisi les mauvaises mesures à consulter? Dans Perfmon ou SQL Profiler?
  3. En ce qui concerne Stored Procedure/SP:Recompileet les TSQL/SQL:StmtRecompileévénements dans SQL Profiler ... ils n'incluent pas la métrique Durée. Comment puis-je évaluer l'impact de ces événements sur le système s'ils ne fournissent aucun moyen de voir l'impact temporel sur le système.

Réponses:


33

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.).


9

Il existe trois compteurs pertinents qui doivent être enregistrés à l'aide de PerfMon (ou d'une autre solution tierce). Le point clé est d' enregistrer ces statistiques d'une manière ou d'une autre.

  • Statistiques SQL \ Demandes de lot / s
  • Statistiques SQL \ Compilations SQL / s
  • Statistiques SQL \ Recompilations SQL / s

Comme Thomas Stringer l'a mentionné , il est bon de garder un œil sur le ratio de compilations / demande de batch. Évidemment, plus c'est bas, mieux c'est, mais il n'y a que des lignes directrices pour ce qui est «bon», et vous seul pouvez décider de ce qui est acceptable. La quantité absolue de gain de performance que vous verrez en réduisant le nombre de compilations dépend de nombreux facteurs.

J'aime aussi regarder le ratio de recompilations / compilation , pour avoir une idée de la quantité de réutilisation du plan de requête. Encore une fois, plus c'est bas, mieux c'est. Dans ce cas, cependant, vous ne souhaitez pas que les recompilations se produisent dans le système à mesure que les statistiques changent (si la base de données est en lecture seule et que vous avez des recompilations ... quelque chose peut être incorrect). Comme je l'ai dit précédemment, il n'y a que des lignes directrices pour ce qui est «bon».

Ce que vous voulez vraiment faire, c'est faire évoluer ces chiffres au fil du temps, donc si vous voyez un pic énorme dans l'un ou l'autre des ratios, quelque chose s'est déployé qui n'utilise pas correctement les plans de requête (idéalement, cela est détecté pendant les tests) - utilisez Shark's analyse les requêtes pour trouver les coupables. De plus, en voici une pour trouver des requêtes fréquemment recompilées:

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

Si vous enregistrez également des statistiques d'utilisation du processeur, toutes les statistiques peuvent être corrélées ensemble pour savoir à quel point cela fait mal et à quel point vos correctifs vous aident. En pratique, j'ai constaté que même une seule stratégie de plan de requête incorrecte sur un sproc de base peut mettre un serveur à genoux; évidemment YMMV.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.