Pourquoi n'utiliserais-je PAS l'option SQL Server «Optimiser pour les charges de travail ad hoc»?

49

Je lisais d'excellents articles sur la mise en cache de plans SQL Server par Kimberly Tripp, tels que celui-ci: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Pourquoi existe-t-il même une option pour "optimiser les charges de travail ad hoc"? Cela ne devrait pas toujours être sur? Que les développeurs utilisent du SQL ad hoc ou non, pourquoi ne pas activer cette option sur toutes les instances qui le prennent en charge (SQL 2008+), réduisant ainsi le fardeau de la mémoire cache?

Un gars
la source

Réponses:

45

L'équipe de développement de SQL Server fonctionne sur le principe de la moindre surprise - de sorte que SQL Server dispose généralement de nouvelles fonctionnalités désactivées afin de préserver le comportement des versions précédentes.

Oui, l'optimisation pour les charges de travail ad hoc permet de réduire considérablement le fardeau de la mémoire cache du plan - mais testez-le toujours en premier!

[Edit: Kalen Delaney raconte une anecdote intéressante. Elle a demandé à l’un de ses amis ingénieurs de Microsoft s’il y aurait des circonstances dans lesquelles il ne serait pas approprié de permettre cela. Il revient plusieurs jours plus tard pour dire: imaginez une application qui a BEAUCOUP de requêtes différentes et chaque requête s'exécute exactement deux fois au total. Ensuite, cela pourrait être inapproprié. Autant dire qu'il n'y a pas beaucoup d'applications comme ça!]

[Edit: Si la majorité de vos requêtes sont exécutées plus d'une fois (pas exactement deux fois); ce serait probablement inapproprié. La règle générale serait de l'activer s'il y a beaucoup de requêtes ad hoc à usage unique sur la base de données; Cependant, il n'y a toujours pas beaucoup d'applications comme ça.]

Peter Schofield
la source
9
Les nouvelles fonctionnalités +1 sont très, très rarement activées par défaut. Je ne vois aucune bonne raison de ne pas activer cette fonctionnalité spécifique. Au pire des cas, toutes vos requêtes sont à usage unique et ne tireraient aucun avantage de la mise en cache de toute façon.
Aaron Bertrand
1
Ceci est une réponse "sûre" basée sur le bon sens et ne répond pas à la question. Le demandeur souhaite connaître spécifiquement le cas d'utilisation pour lequel il est préférable d'activer NON cette fonctionnalité.
MikeTeeVee
2
MikeTeeVee - cela pourrait être une réponse sûre, mais c’est l’une de ces caractéristiques pour lesquelles je ne peux vraiment pas penser à une raison de ne pas l’activer. Comme il est si génial, je voulais juste expliquer pourquoi il était désactivé par défaut!
Peter Schofield
21

Vous trouverez ci-dessous un petit code qui vous aidera à décider si "activer / désactiver l' optimisation pour les charges de travail ad hoc " sera bénéfique ou non. Nous vérifions généralement cela dans le cadre de notre bilan de santé pour les serveurs internes et clients.

C'est l'option la plus sûre à activer et elle est bien décrite par Brad ici et par Glenn Berry ici .

--- for 2008 and up .. Optimize ad-hoc for workload 
IF EXISTS (
        -- this is for 2008 and up
        SELECT 1
        FROM sys.configurations
        WHERE NAME = 'optimize for ad hoc workloads'
        )
BEGIN
    DECLARE @AdHocSizeInMB DECIMAL(14, 2)
        ,@TotalSizeInMB DECIMAL(14, 2)
        ,@ObjType NVARCHAR(34)

    SELECT @AdHocSizeInMB = SUM(CAST((
                    CASE 
                        WHEN usecounts = 1
                            AND LOWER(objtype) = 'adhoc'
                            THEN size_in_bytes
                        ELSE 0
                        END
                    ) AS DECIMAL(14, 2))) / 1048576
        ,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
    FROM sys.dm_exec_cached_plans

    SELECT 'SQL Server Configuration' AS GROUP_TYPE
        ,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '.  Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
        ,' ' + CASE 
            WHEN @AdHocSizeInMB > 200
                OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
                THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
            ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
            END + ' ' AS RECOMMENDATIONS
END
Kin Shah
la source
7

Pensez à un serveur de production qui ne traite que 5 requêtes différentes, mais plusieurs milliers par seconde. Vous êtes l'équipe de développement de Microsoft SQL Server. Vous allez bricoler avec la mise en cache des plans. Activez-vous ce comportement par défaut lorsque vous savez que certains de vos clients les plus importants et les plus critiques (par exemple, l'implémentation SAP interne de Microsoft) travaillent sur le même campus et utilisent la même cafétéria que vous?

Stu
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Paul White
7

Lorsque vous activez l' option " Optimiser pour les charges de travail ad hoc ", les requêtes ad-hoc exécutées la deuxième fois sont aussi lentes que la première, car vous allez compiler un plan d'exécution et extraire les mêmes données ( sans le mettre en cache) ces 2 premières fois.
Ce n'est peut-être pas grave, mais vous le remarquerez lors du test des requêtes.
Alors que se passe-t-il maintenant, sans cette option activée et un cache plein de requêtes Ad-Hoc 1-Off?

L'algorithme de gestion de la mise en cache:

Lorsque cette fonctionnalité d'optimisation a été introduite, l'algorithme de gestion de la mise en cache a également été mis à jour.
L'article de Kimberly Tripp fait également référence à l'article de Kalen Delaney sur ce changement d'algorithme.
Elle explique le mieux:

La modification calcule en fait une taille de cache de plan à laquelle SQL Server reconnaît qu'il existe une pression de mémoire et commence à supprimer les plans du cache. Les plans à supprimer sont les plans bon marché qui n'ont pas été réutilisés, et c'est une bonne chose.

Cela signifie que ces plans fastidieux à minuterie unique seront les premiers à disparaître lorsque vous aurez besoin de libérer des ressources.

Alors maintenant, la question devient:

    « Pourquoi avons-nous besoin « Optimize pour les workloads ad hoc » lorsque SQL Server prend en charge la suppression des plans non utilisés en cas de besoin? »

Ma réponse à cette question est, si vous avez régulièrement une s-tonne de oodles de production-sql dynamiques de publicité non-paramétrés -hoc, il est donc logique d'activer cette fonctionnalité.
Vous souhaitez éviter de surcharger les ressources système, de manière à forcer la suppression de la planification / du plan mis en cache une fois que vous avez utilisé au maximum la mémoire cache.

Comment savoir quand j'ai besoin de l'activer?

Voici une requête que j'ai écrite pour vous montrer combien de plans ad-hoc que vous avez actuellement mis en cache et combien d'espace disque ils consomment (les résultats changeront au cours de la journée - testez-le pendant une période de forte charge):

--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
       S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
       CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
       S.Total_MB_1_Use,   S.Total_MB,
       CAST( (S.Total_MB_1_Use   * 1.0 / S.Total_MB  ) as Decimal(18,2) )[Pct_MB_1_Use]
  FROM
  (
    SELECT CP.objtype[CacheType],
           COUNT(*)[Total_Plan],
           SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
           SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
           SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
           CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
           CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
                      / 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
           CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
           CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
                         ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
      FROM sys.dm_exec_cached_plans as CP
     GROUP BY CP.objtype
  ) AS S
 ORDER BY S.CacheType

Résultats: entrez la description de l'image ici

Je ne vais pas dire " Quand vous avez X MB " ou " Si X% de vos Ad Hoc sont à usage unique " pour l'activer.
Cela n'affecte pas les Sprocs, les déclencheurs, les vues ni les instructions SQL préparées / préparées, mais uniquement les requêtes ad hoc.
Ma recommandation personnelle est simplement d'activer votre environnement de production, mais d'envisager de le laisser dans votre environnement de développement.
Je ne dis cela que pour Dev, car si vous optimisez une requête qui prend une minute ou plus à s'exécuter, vous ne voulez pas l'exécuter 3 fois avant de voir à quelle vitesse elle ira avec elle mise en cache - chaque Une seule fois, vous la modifiez pour trouver la meilleure conception d'optimisation.
Si votre travail ne consiste pas à le faire toute la journée, allez-y et demandez à votre DBA de l'activer partout.

MikeTeeVee
la source
0

"Pourquoi ne devrais-je PAS utiliser ...." Au cours de certaines enquêtes de performance, extraire les plans du cache de plans presque en temps réel tout en surveillant l'utilisation des ressources peut s'avérer très utile. "Optimiser pour les charges de travail ad hoc" peut perturber cela, car les plans de stub ad hoc ne renverront pas de plan lors de l'interrogation du cache. Dans un cas comme celui-ci, si la requête et le plan ne peuvent pas être identifiés, le paramètre peut être activé et désactivé à des fins d’enquête. Notez qu'un changement dans la définition des requêtes d'effets compilées à partir de ce moment. En outre, chaque fois que vous modifiez une propriété 'serveur', vérifiez sur une instance non-produit de la même version pour vérifier si la modification videra ou non le cache de plan. Personnellement, je déteste être surpris par cela. (Par exemple, la modification de maxdop au niveau du serveur supprime généralement le cache du plan,

"Aucun rapport d'exécution n'est associé au stub du plan compilé et l'interrogation du descripteur de plan ne renvoie pas de Showplan XML." http://technet.microsoft.com/en-us/library/cc645587.aspx

sql_handle
la source