Domanda

Ho due domande quasi identiche in esecuzione sullo stesso SQL Server 2005:

  1. Il primo è la query SELECT originale come generato da LINQ (lo so, lo so ... Io non sono lo sviluppatore dell'applicazione, solo il DBA:).
  2. La seconda è esattamente lo stesso come il primo, aggiunto un OPTION (RECOMPILE) alla fine.

Niente altro è stato cambiato.

La prima dura 55 secondi ogni volta che la sua corsa.
La seconda prende 2 secondi.

Entrambi i set di risultati sono identici.

Perché questo suggerimento generare un guadagno in termini di prestazioni così drammatico?

La voce Documentazione in linea su RECOMPILE non offre una spiegazione molto dettagliata:

Istruisce il database di SQL Server Motore di scartare il piano generato per la query dopo aver eseguito, costringendo il Query Optimizer ricompilare un piano di query la prossima volta che si esegue la stessa query. Senza specificare RECOMPILE, il motore di database cache di query piani e li riutilizza. Durante la compilazione di query piani, l'hint di query RECOMPILE utilizza i valori correnti di tutte le variabili locali nella query e, se la query è all'interno di una stored procedure, i valori correnti passati al eventuali parametri.

RECOMPILE è un'utile alternativa alla creazione di una stored procedure utilizza la clausola WITH RECOMPILE quando solo un sottoinsieme di query all'interno la stored procedure, anziché l'intera procedura memorizzata, deve essere ricompilato. Per ulteriori informazioni, vedere la ricompilazione di stored procedure. RECOMPILE è utile anche quando si crea guide di piano. Per più informazioni, vedere Ottimizzazione delle query nelle applicazioni distribuite tramite le Guide di piano.

Dal momento che la mia domanda ha un sacco di variabili locali, la mia ipotesi è che SQL Server è in grado di (serio) ottimizzarlo quando uso il suggerimento di query OPTION (RECOMPILE).

ovunque guardo la gente sta dicendo che OPTION (RECOMPILE) dovrebbe essere evitato. La spiegazione di questo è in genere che l'utilizzo di questo suggerimento di SQL Server non è in grado di riutilizzare questo piano con elaborazione e quindi deve perdere tempo ricompilazione che ogni volta
. (Ma) Dato il vantaggio prestazionale gigantesca, io sono incline a pensare che l'uso questa query suggerimento questa volta sarebbe una buona cosa.

Qualora lo uso? In caso contrario, c'è un modo posso forzare SQL Server per utilizzare una migliore piano di esecuzione senza questo suggerimento e senza alterare l'applicazione?

È stato utile?

Soluzione

Come documentato nell'articolo statistiche utilizzate da Query Optimizer in Microsoft SQL Server 2005

Se si utilizza una variabile locale in un predicato di query al posto di un dei parametri o letterali, le stazioni ottimizzatore di una ridotta qualità stimare, o una supposizione per la selettività del predicato. Utilizzare i parametri o letterali nella query, invece di variabili locali

Quando l'ottimizzatore non dispone di statistiche utilizzabile a tutti per una colonna lo farà indovinare che un predicato = abbinerà il 10% di righe, BETWEEN 9%, e una delle >, >=, < and <= corrisponderà al 30%. Se ci sono statistiche di colonna disponibili un predicato = saranno trattati in modo diverso, come di seguito.

Anche quando le variabili locali sono utilizzati in una query, una stima che è meglio di una congettura viene utilizzato in caso di predicati di uguaglianza. Selettività per le condizioni di forma "@local_variable = column_name" è stimato usando la frequenza media valore dal istogramma column_name. Così, per esempio, se La colonna contiene tutte valori unici, quindi si utilizzerà una stima selettività di 1/(number of unique values in column), che è preciso.

Quindi questo è essenzialmente la stessa cosa che usare per OPTIMIZE FOR (UNKNOWN). Può ben essere più preciso di una congettura 10% piatto, ma non è su misura per i valori specifici che si sta eseguendo la query.

Per forzare SQL Server per ottimizzare una query ogni volta che viene eseguito, e l'uso i valori delle variabili locali per stima di cardinalità e costi durante l'ottimizzazione della query, aggiungere il suggerimento di query RECOMPILE alla query.

Con l'uso di RECOMPILE voi probabilmente stanno ottenendo stime di cardinalità più precise e quindi un piano diverso con unirsi ordini / unirsi tipi più adatto al numero di righe restituite da diverse parti della query attuale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top