Perché NON dovrei usare l'opzione "Ottimizza per carichi di lavoro ad hoc" di SQL Server?


49

Ho letto alcuni grandi articoli sulla memorizzazione nella cache del piano di SQL Server di Kimberly Tripp come questo: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Perché esiste anche un'opzione per "ottimizzare i carichi di lavoro ad hoc"? Non dovrebbe essere sempre acceso? Indipendentemente dal fatto che gli sviluppatori utilizzino o meno SQL ad hoc, perché non dovresti avere questa opzione abilitata su ogni istanza che lo supporta (SQL 2008+), riducendo così il gonfiore della cache?

Risposte:


45

Il team di sviluppo di SQL Server lavora secondo il principio della minima sorpresa, quindi in genere SQL Server ha nuove funzionalità disabilitate nell'interesse di mantenere il comportamento delle versioni precedenti.

Sì, l'ottimizzazione per i carichi di lavoro ad hoc è ottima per ridurre il gonfiore della cache del piano, ma testalo sempre prima!

[Modifica: Kalen Delaney racconta a un aneddoto interessante di aver chiesto a uno dei suoi amici ingegneri Microsoft se ci fossero circostanze in cui non sarebbe stato appropriato abilitarlo. Torna alcuni giorni dopo per dire: immagina un'applicazione che ha MOLTE query diverse e ogni query viene eseguita esattamente due volte in totale. Quindi potrebbe essere inappropriato. Basti dire che non ci sono molte app del genere!]

[Modifica: se la maggior parte delle tue query viene eseguita più di una volta (non esattamente due volte); sarebbe probabilmente inappropriato. La regola generale sarebbe di cambiarla se ci sono molte query ad hoc monouso nel database; tuttavia, non ci sono ancora molte app del genere.]


9
+1 le nuove funzionalità sono attivate molto, molto raramente per impostazione predefinita. Non riesco davvero a pensare a nessuna buona ragione per non attivare questa funzione specifica - nel peggiore dei casi tutte le tue query sono monouso e non trarrebbero comunque alcun vantaggio dalla memorizzazione nella cache.
Aaron Bertrand

1
Questa è una risposta "sicura" basata sul buon senso e non affronta la domanda. Il richiedente desidera conoscere specificamente il caso d'uso per quando NON attivare questa funzione è migliore.
MikeTeeVee,

2
MikeTeeVee - potrebbe essere una risposta sicura, ma questa è una di quelle caratteristiche in cui non riesco davvero a pensare a un motivo per non abilitarlo. Dal momento che è così fantastico, volevo solo spiegare perché era disattivato per impostazione predefinita!
Peter Schofield,

21

Di seguito è riportato un piccolo codice che ti aiuterà a decidere se "attivare / disattivare la commutazione ottimizzata per carichi di lavoro ad hoc " sarà utile. Normalmente lo controlliamo come parte del nostro controllo dello stato per server interni e client.

È l'opzione più sicura da abilitare ed è descritta bene da Brad qui e da Glenn Berry qui .

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

7

Pensa a un server di produzione che serve solo 5 query diverse, ma diverse migliaia di quelle al secondo. Sei il team di sviluppo di Microsoft SQL Server. Stai per giocherellare con la memorizzazione nella cache del piano. Attivi questo comportamento per impostazione predefinita, quando sai che alcuni dei tuoi clienti più grandi e critici (ad esempio, l'implementazione SAP interna di Microsoft) lavorano nello stesso campus e usano la stessa caffetteria che fai?


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Paul White

7

Quando si attiva l'opzione " Ottimizza per carichi di lavoro ad hoc", le query ad hoc eseguite la seconda volta saranno lente quanto la prima, poiché si compilerà un piano di esecuzione e si estrarranno gli stessi dati ( senza che sia memorizzato nella cache) quelle prime 2 volte.
Questo potrebbe non essere un grosso problema, ma lo noterai quando testerai le query.
Cosa succede ora, senza questa opzione attivata e una cache piena di query 1-Off Ad-Hoc?

L'algoritmo di gestione della cache:

Quando è stata introdotta questa funzionalità di ottimizzazione, è stato aggiornato anche l'algoritmo di gestione della cache.
L'articolo di Kimberly Tripp fa riferimento anche al post di Kalen Delaney su questa modifica dell'algoritmo.
Lo spiega meglio:

La modifica calcola effettivamente una dimensione della cache del piano in base alla quale SQL Server riconosce la pressione della memoria e inizierà a rimuovere i piani dalla cache. I piani da rimuovere sono i piani economici che non sono stati riutilizzati, e questa è una buona cosa.

Ciò significa che quei fastidiosi piani con un solo timer saranno i primi ad andare quando devi liberare risorse.

Quindi ora la domanda diventa:

    " Perché ABBIAMO BISOGNO di" Ottimizzare per i carichi di lavoro ad hoc "quando SQL Server si occupa di rimuovere i piani inutilizzati quando necessario? " La

mia risposta è che se si dispone regolarmente di una tonnellata di dinamici sql che generano una gran quantità di annunci non parametrizzati -hoc query, quindi ha perfettamente senso attivare questa funzione.
Si desidera evitare di mettere a dura prova le risorse di sistema, in modo tale da forzare la rimozione di dati / cache dopo aver esaurito lo spazio di memoria della cache massima.

Come faccio a sapere quando devo accenderlo?

Ecco una query che ho scritto per mostrarti quanti piani Ad-Hoc hai attualmente memorizzato nella cache e quanto spazio su disco stanno esaurendo (i risultati cambieranno durante il giorno, quindi testalo durante un periodo di carico pesante):

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

risultati: inserisci qui la descrizione dell'immagine

Non dirò " Quando hai X MB " o " Se l'X% dei tuoi annunci ad hoc sono monouso " per attivarlo.
Non influisce su Sprocs, trigger, viste o SQL con parametri / preparati: solo le query ad hoc.
Il mio consiglio personale è di attivarlo nel tuo ambiente di produzione, ma considera di lasciarlo nel tuo ambiente di sviluppo.
Lo dico solo per Dev, perché se stai ottimizzando una query che richiede un minuto o più per essere eseguita, non vuoi eseguirla 3 volte prima di poter vedere quanto velocemente andrà con la cache - ogni una volta che lo modifichi per trovare il miglior design di ottimizzazione.
Se il tuo lavoro non prevede di farlo tutto il giorno, impazzisci e chiedi al tuo DBA di attivarlo ovunque.


0

"Perché NON dovrei usare ...." Nel corso di alcune indagini sulle prestazioni, estrarre i piani dalla cache dei piani in tempo reale, osservando l'utilizzo delle risorse può essere molto utile. "Ottimizza per carichi di lavoro ad hoc" potrebbe interrompere ciò, poiché i piani di stub ad hoc non restituiranno un piano durante l'interrogazione della cache. In un caso del genere, se altrimenti la query e il piano non possono essere identificati, l'impostazione potrebbe essere attivata e disattivata per motivi di indagine. Si noti che un cambiamento nell'impostazione delle query degli effetti è stato compilato da quel punto in avanti. Inoltre, ogni volta che si modifica una proprietà 'server', verificare su un'istanza non prodotto nella stessa versione per verificare se la modifica scaricherà o meno la cache del piano. Personalmente odio essere sorpreso da questo. (Ad esempio, la modifica di maxdop a livello di server in genere svuota la cache del piano,

"Lo stub del piano compilato non ha un piano di esecuzione associato e la query per l'handle del piano non restituirà uno Showplan XML." http://technet.microsoft.com/en-us/library/cc645587.aspx

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.