Domanda

Comprendo che l'opzione WITH RECOMPILE forza l'ottimizzatore a ricostruire il piano di query per i processi memorizzati ma quando vorresti che ciò accadesse?

Quali sono alcune regole pratiche su quando usare l'opzione WITH RECOMPILE e quando non farlo?

Qual è l'overhead efficace associato al semplice inserimento in ogni sproc?

È stato utile?

Soluzione

Come altri hanno già detto, non si desidera semplicemente includere WITH RECOMPILE in ogni processo memorizzato come una questione di abitudine. In tal modo, elimineresti uno dei principali vantaggi delle procedure memorizzate: il fatto che salva il piano di query.

Perché è potenzialmente un grosso problema? Il calcolo di un piano di query è molto più intenso della compilazione di un normale codice procedurale. Poiché la sintassi di un'istruzione SQL specifica solo cosa e non (in generale) come ottenerlo, ciò consente al database un ampio grado di flessibilità durante la creazione del fisico piano (ovvero le istruzioni dettagliate per raccogliere e modificare effettivamente i dati). Ci sono molti "trucchi" il pre-processore delle query del database può fare e le scelte che può fare: quale ordine di unire le tabelle, quali indici usare, se applicare le clausole WHERE prima o dopo i join, ecc.

Per una semplice istruzione SELECT, potrebbe non fare la differenza, ma per qualsiasi query non banale, il database impiegherà un po 'di tempo (misurato in millisecondi, al contrario dei soliti microsecondi) per trovare un piano ottimale. Per query davvero complesse, non può nemmeno garantire un piano ottimale , deve solo usare l'euristica per elaborare un piano abbastanza buono . Quindi costringendolo a ricompilarsi ogni volta, gli stai dicendo che deve passare attraverso quel processo ancora e ancora, anche se il piano che ha ottenuto prima era perfettamente buono.

A seconda del fornitore, dovrebbero esserci trigger automatici per la ricompilazione dei piani di query - ad esempio, se le statistiche su una tabella cambiano in modo significativo (come l'istogramma dei valori in una determinata colonna che inizia in modo uniforme distribuito nel tempo diventa fortemente distorto ), il DB dovrebbe notarlo e ricompilare il piano. Ma in generale, gli implementatori di un database saranno più intelligenti di quello che sei.

Come per qualsiasi cosa legata alle prestazioni, non fare scatti al buio; capire dove sono i colli di bottiglia che costano il 90% delle prestazioni e risolverli per primi.

Altri suggerimenti

Inserirlo in ogni procedura memorizzata NON è una buona idea, poiché la compilazione di un piano di query è un'operazione relativamente costosa e non si vedrà alcun vantaggio dal fatto che i piani di query vengano memorizzati nella cache e riutilizzati.

Il caso di una dinamica in cui la clausola costruita all'interno di una procedura memorizzata può essere gestita usando sp_executesql per eseguire il TSQL anziché aggiungere WITH RECOMPILE alla procedura memorizzata.

Un'altra soluzione (da SQL Server 2005 in poi) è usare l'hint con parametri specifici usando l'hint OPTIMIZE FOR . Funziona bene se i valori nelle righe sono statici.

SQL Server 2008 ha introdotto un caratteristica poco conosciuta chiamata " OTTIMIZZA PER SCONOSCIUTO " ;:

  

Questo suggerimento indirizza Query Optimizer   per usare gli algoritmi standard che ha   usato sempre se non ci sono valori di parametri   era stato passato alla query.   In questo caso verrà visualizzato l'ottimizzatore   a tutti i dati statistici disponibili a   raggiungere una determinazione di ciò che il   valori delle variabili locali utilizzate   generare il queryplan dovrebbe essere,   invece di guardare allo specifico   valori dei parametri a cui sono stati passati   la query dall'applicazione.

L'uso più comune è quando potresti avere una clausola WHERE dinamica in una procedura ... non vorrai che quel particolare piano di query venga compilato e salvato per le esecuzioni successive perché potrebbe benissimo non essere esattamente la stessa clausola la prossima volta che viene chiamata la procedura.

generalmente un'alternativa molto migliore a WITH RECOMPILE è OPTION (RECOMPILE) come puoi vedere nella spiegazione seguente, presa da la risposta a questa domanda qui

  

Quando si verifica un problema di sensibilità dei parametri, un pezzo comune di   consigli su forum e Q & A; siti è di "utilizzare la ricompilazione" (assumendo il   altre opzioni di ottimizzazione presentate in precedenza non sono adatte). Sfortunatamente,   tale consiglio è spesso interpretato erroneamente con l'aggiunta di WITH RECOMPILE   opzione per la procedura memorizzata.

     

L'uso di WITH RECOMPILE ci riporta effettivamente a SQL Server 2000   comportamento, in cui l'intera procedura memorizzata viene ricompilata su ogni   esecuzione. Un'alternativa migliore, su SQL Server 2005 e versioni successive, è   utilizzare il suggerimento per la query OPTION (RECOMPILE) solo sull'istruzione   soffre del problema di sniffing dei parametri. Questo suggerimento per la query risulta   in una ricompilazione della sola dichiarazione problematica; piani di esecuzione   per altre istruzioni all'interno della procedura memorizzata vengono memorizzate nella cache e riutilizzate   come normale.

     

L'uso di WITH RECOMPILE significa anche il piano compilato per l'archiviazione   la procedura non è memorizzata nella cache. Di conseguenza, nessuna informazione sulle prestazioni è   gestito in DMV come sys.dm_exec_query_stats. Utilizzando la query   suggerimento invece significa che un piano compilato può essere memorizzato nella cache e prestazioni   le informazioni sono disponibili nei DMV (sebbene siano limitate al massimo   esecuzione recente, solo per l'istruzione interessata).

     

Per le istanze che eseguono almeno SQL Server 2008 build 2746 (servizio   Pack 1 con Aggiornamento cumulativo 5), usando OPTION (RECOMPILE) ne ha un altro   vantaggio significativo rispetto a WITH RECOMPILE: solo OPTION (RECOMPILE)   abilita l'ottimizzazione dell'incorporamento dei parametri.

Dovrebbe essere usato solo quando il test con dati rappresentativi e il contesto dimostra che fare a meno produce piani di query non validi (qualunque siano i possibili motivi). Non dare per scontato (senza test) che un SP non si ottimizzi correttamente.

Eccezione unica solo per l'invocazione manuale (ovvero non codificarlo nell'SP): quando sai che hai modificato sostanzialmente il carattere delle tabelle di destinazione. per esempio. TRUNCATE, carichi in blocco, ecc.

È l'ennesima opportunità per l'ottimizzazione prematura.

Nota: ho molti punti. Se un nuovo arrivato invia la stessa risposta di seguito e l'utente accetta, vota per favore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top