Database
 sql >> Database >  >> RDS >> Database

Domande e risposte dalla nostra serie di webinar sullo sniffing dei parametri

Negli ultimi due mercoledì abbiamo ospitato una serie di webinar in due parti che trattava i problemi di sensibilità dei parametri:

  • Procedure memorizzate, parametri, problemi...
    Kimberly L. Tripp e Aaron Bertrand
    24 gennaio
    Ti sei perso? Registrati per guardarlo ora!

  • Affrontare lo sniffing dei parametri utilizzando SentryOne
    Aaron Bertrand, Kimberly L. Tripp e Andy Mallon
    31 gennaio
    Ti sei perso? Guardalo ora!

Durante entrambi i webinar sono emerse alcune domande e ho pensato di compilarle e rispondere qui (alcune delle risposte sono arrivate da Andy durante il webinar).

In un problema che abbiamo visto di recente, stiamo vedendo che i piani vengono eliminati dalla cache molto rapidamente. Non stiamo eseguendo nulla da te descritto (DBCC FREEPROCCACHE eccetera.); la pressione della memoria potrebbe causare anche questo?

Sì, la pressione della memoria potrebbe essere un fattore (vedi questo post) e so che ci sono alcune indagini su potenziali problemi con la gestione della memoria di SQL Server anche a questo proposito.

Da un partecipante:"Non una domanda, ma un commento all'utente che chiedeva delle molte volte che la sua cache del piano è stata svuotata. Avevamo anche quello e, in effetti, era una pressione della memoria. Avevamo la memoria massima del server configurata in modo errato, era risolto utilizzando la formula menzionata qui, e quindi abbiamo eseguito la procedura di questo articolo ogni 10 minuti (abbiamo tonnellate di SQL dinamico, usato solo una volta)."

Cosa succede se usi OR nella clausola where invece di AND , il problema persiste?

In genere se usi OR in questo tipo di pattern, otterrai ogni volta tutte le righe, a meno che ogni singolo parametro non venga popolato con valori che filtrano le righe. Questo cambia la semantica della query da "tutte queste cose devono essere vere" a "qualsiasi di queste cose può essere vera". Tuttavia, il piano compilato per il primo set di parametri verrà comunque memorizzato nella cache e mantenuto per le esecuzioni future, indipendentemente dal fatto che le tue clausole utilizzino AND o OR .

È 1=1 segnala un buon approccio? Non è meglio aggiungere solo i parametri forniti e quindi evitare il brutto 1=1 ?

Il 1 = 1 viene praticamente ignorato da SQL Server, ma consente di aggiungere tutte le clausole condizionali con AND in modo da non dover trattare il *primo* in modo diverso. Ecco l'alternativa:

SET @IncludedWhereClauseYet bit = 0;
SET @sql = N'SELECT cols FROM dbo.Table';
 
IF @param1 IS NOT NULL
BEGIN
  IF @IncludedWhereClauseYet = 0
  BEGIN
    SET @sql += N' WHERE ';
    SET @IncludedWhereClauseYet = 1;
  END
  ELSE
  BEGIN
    SET @sql += N' AND ';
  END
  SET @sql += N' @param1 = @param1';
END
 
IF @param2 IS NOT NULL
BEGIN
  IF @IncludedWhereClauseYet = 0
  ...
END
...

Il 1=1 ti permette di semplificare, permettendoti di anteporre sempre a qualsiasi clausola AND . Il codice sopra diventa:

SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1';
 
IF @param1 IS NOT NULL
BEGIN
  SET @sql += N' AND @param1 = @param1';
END
 
IF @param2 IS NOT NULL
BEGIN
  SET @sql += N' AND @param2 = @param2';
END

Potresti forse usare una clausola iniziale diversa per evitare tutti i condizionali, come WHERE PrimaryKey > 0 o WHERE PrimaryKey IS NOT NULL , e quindi ogni clausola successiva potrebbe iniziare con AND . Ma 1 = 1 , sebbene brutto, è innocuo e IMHO non è meno brutto dell'aggiunta di una clausola *reale* ma priva di significato, tranne per il fatto che una clausola *reale* potrebbe influire sul piano.

Ricorda che quando stai costruendo codice T-SQL con T-SQL, hai due aspetti di "brutto" a cui pensare:a volte risolverai il codice sopra e a volte risolverai la query che esce da esso. Fai attenzione a sacrificarne uno per il bene dell'altro.

CHE COSA?! L'ho completamente perso... WITH RECOMPILE . Pensavo che questo avesse svuotato il piano, ma lo lascia solo solo per questa esecuzione... è molto importante da sapere!

Assicurati solo di essere consapevole anche degli aspetti negativi.
Guarda questo fantastico post di Paul White.

OPTION OPTIMIZE FOR @parametername UNKNOWN non è più preferito nelle versioni SQL più recenti?

Non penso che sia migliore o peggiore nelle versioni moderne rispetto a quando è stato introdotto per la prima volta in SQL Server 2008. Per quanto ne so, anche con tutte le modifiche all'ottimizzatore e allo stimatore di cardinalità, quel bit si comporta ancora allo stesso modo.

C'è del carico sul server, se abilito l'acquisizione delle statistiche delle procedure e delle query in SentryOne?

La raccolta di statistiche di procedure e query dovrebbe essere attiva per impostazione predefinita. Tutta la raccolta dei dati ha un costo, ma SQL Sentry è abbastanza attento a quanto costa la raccolta.

La ricerca su RS non lo utilizzava come predicato residuo, ma cercava qualcos'altro che non riuscivo a vedere.

Grazie, rivedrò quell'esempio e scriverò un blog sulle demo separatamente, assicurandomi di includere tutti i dettagli rilevanti che non erano evidenti dal solo diagramma del piano.

Non è vero che aggiungere alcune delle colonne necessarie come INCLUDE s in realtà non rendono l'indice più efficace perché la ricerca della chiave non verrà eliminata? Sto pensando che la percentuale non dovrebbe cambiare a meno che tu non elimini effettivamente la ricerca della chiave.

A rigor di termini, sì, è vero. La query originale era un pessimo esempio, usando SELECT * e un indice mancante di un numero disperato di colonne. Il punto che stavo cercando di sottolineare è che la scheda Analisi dell'indice ti incoraggia sia a (a) migliorare la query che (b) a coprire l'indice. Il punteggio è lì per invogliarti a fare una o entrambe:se modifichi la query in modo da aver bisogno di meno colonne, anche l'indice si avvicina a coprire la query. Se intendi creare un nuovo indice di copertura separato, hai anche le informazioni su quali colonne sono necessarie per coprire questa specifica query. Tecnicamente, hai ragione, aggiungere una colonna di inclusione ma richiedere comunque una ricerca per altre 4 non migliorerà le prestazioni di questa specifica query e non migliorerà l'indice, ma indica che tu' ti stai avvicinando La speranza è che non ti fermi ad aggiungere solo una colonna di inclusione e ignori il resto. Non sappiamo quando smetterai, quindi non so se esiste una soluzione perfetta, non vogliamo certo scoraggiare utenti dal rendere i loro indici più adatti alle loro query.

Perché vediamo query che utilizzano il parametro del nome e il parametro del cognome riepilogati in un'istruzione che utilizza solo un parametro del cognome?

AGGIORNAMENTO: Questo è intenzionale. Il raggruppamento in Mostra totali raggruppa la stessa procedura chiamata con tutte le varie combinazioni di parametri. Quindi puoi usarlo prima per determinare quali parametri tendono a causare le prestazioni peggiori, quindi, all'interno di questo, approfondire se c'è o meno una distorsione dei dati. Un parametro che porta a una ricerca su una colonna non indicizzata, ad esempio, probabilmente risulterà in alto in modo abbastanza affidabile, e puoi vederlo in combinazione con altri parametri che vengono passati e anche confrontati con tutte le chiamate in cui quel parametro era ' t passato.

Detto questo, cercheremo di mettere a punto questo comportamento di raggruppamento mentre completiamo le modifiche attualmente in corso per la schermata SQL principale.

Esiste documentazione su come utilizzare una guida al piano? Al momento non avrei idea di come farlo.

Questo è qualcos'altro di cui volevo scrivere un blog, ma nel frattempo Microsoft ha alcuni argomenti qui (e controlla tutti i collegamenti correlati nella barra laterale).

Devo abilitare qualcosa per ottenere il grafico della cronologia delle query?

No, dovrebbe essere abilitato su tutte le versioni moderne dell'applicazione client SentryOne. Se non lo vedi, prova Tools > Reset Layout; se non funziona, contatta [email protected].

Ci sono casi in cui si forza l'ultimo piano valido noto utilizzando Query Store quando una regressione del piano viene trovata una cattiva idea? Questo tenderà a nascondere i problemi che possono essere affrontati meglio modificando la dichiarazione come hai mostrato?

Forzare un piano è spesso un'opzione di ultima istanza e tendo a riservarla ai casi in cui davvero, davvero, davvero non puoi correggere l'affermazione (o cambiare l'indice). Forzare un piano può sempre portare a un comportamento sbagliato, perché è ancora un essere umano a fare quella scelta e potresti farlo sulla base di informazioni sbagliate. La regressione potrebbe essere dovuta a una modifica del piano, ma se la consideri una regressione perché il tempo di esecuzione era più lungo, hai studiato altre possibili ragioni? Ad esempio, supponiamo che il sistema sia stato riavviato o si sia verificato un failover e abbia ottenuto un nuovo piano perché il vecchio è stato sfrattato e forse anche le statistiche sono cambiate nel frattempo, ma ora la query viene eseguita più a lungo non perché il piano è peggiore ma piuttosto perché i buffer erano vuoti. Quindi sì, certamente non suggerirei di forzare un piano su ogni regressione.

SentryOne non acquisisce sempre dati o parametri, quindi non ho informazioni sufficienti. Come posso assicurarmi che SentryOne acquisisca sempre parametri e piani di esecuzione?

Non puoi davvero perché tutto dipende da come vengono eseguite le tue query, da come le acquisiamo e dalla velocità con cui vengono eseguite. Spesso le query non vengono eseguite abbastanza a lungo per essere acquisite completamente e dobbiamo fare affidamento sulle visualizzazioni statistiche di query/procedura aggregate di SQL Server, che non raccolgono informazioni sui parametri. Puoi modificare le impostazioni di raccolta per l'origine SQL principale per acquisire di più e con un intervallo più frequente, ma devi bilanciare la quantità di dati che raccogli con la quantità di informazioni aggiuntive che ti acquista.

Posso richiedere le informazioni in modo da poter automatizzare e generare rapporti?

Non abbiamo nulla fuori dagli schemi per farlo, ma lascia che lo riporti alla squadra e vediamo che tipo di opzioni possiamo trovare. Una cosa con cui ho giocato per questo webinar è stata la creazione di una condizione di avviso per cogliere il tipo di regressione che stiamo cercando, ma il tempo è diventato un fattore determinante.

Come decidiamo quando usare OPTION (RECOMPILE) , come ogni giorno riceviamo piani diversi per parametri diversi?

Direi di iniziare con le query che fluttuano di più con la sensibilità dei parametri. Se ho una query che a volte richiede 2 secondi ma a volte 30 e un'altra che va da 4 secondi a 6 secondi,
mi concentrerò sulla prima.

Quale è meglio usare, OPTION (RECOMPILE) o QUERYTRACEON , nel caso di sniffing dei parametri.

Preferisco OPTION (RECOMPILE) per due ragioni. Uno, è auto-documentante; nessuno che legge il codice si chiederà cosa sta facendo, ma non tutti quelli che leggono il codice avranno memorizzato numeri TF come 4136. Due, non richiede autorizzazioni elevate:prova a utilizzare QUERYTRACEON come un peone.

È possibile allertare o segnalare procedure che richiedono più tempo del solito? I più interessati alle procedure di conteggio elevato.

Assolutamente, potresti usare una condizione di avviso, ma può diventare un po' complicato perché, per procedure che a volte vengono eseguite anche al di sotto della soglia di raccolta, dovresti confrontare le istantanee delle statistiche della procedura DMV. Ho aggiunto un promemoria al blog anche su questo, poiché è qualcosa che ho aiutato i clienti a implementare in passato.

Microsoft sta rendendo l'ottimizzazione automatica predefinita per il database SQL di Azure, inclusa la correzione automatica del piano. Ti sembra una buona idea?

Mi riserverò il giudizio fino a quando io (o alcuni clienti) non avremo giocato con esso. Decidere come sintonizzare è già abbastanza impegnativo per i mortali; i mortali che scrivono software da mettere a punto per te sembrano almeno altrettanto impegnativi, se non di più. Quando Andy ha visto questa domanda, mi ha detto che gli ricordava SQL Server 2000:il discorso di marketing allora era che era così autoregolante che non avremmo più bisogno di DBA. Questa affermazione non è invecchiata bene.

Sarebbe bello poter selezionare i due punti nel grafico della cronologia delle query e confrontarli.

Sono d'accordo.
Resta sintonizzato.