Ho due query quasi identiche in esecuzione sulla stessa istanza di SQL Server 2005:
- La prima è la
SELECT
query originale generata da LINQ (lo so, lo so ... non sono lo sviluppatore dell'applicazione, ma solo il DBA :). - Il secondo è esattamente lo stesso del primo, aggiunto
OPTION (RECOMPILE)
a alla fine.
Nient'altro è stato cambiato.
Il primo impiega 55 secondi ogni volta che si avvia.
Il secondo richiede 2 secondi.
Entrambi i set di risultati sono identici.
Perché questo suggerimento genererebbe un guadagno così drammatico nelle prestazioni?
La voce Libri online su RECOMPILE
non offre una spiegazione molto dettagliata:
Indica a Motore di database di SQL Server di eliminare il piano generato per la query dopo l'esecuzione, forzando Query Optimizer a ricompilare un piano di query alla successiva esecuzione della stessa query. Senza specificare RECOMPILE, Motore di database memorizza nella cache i piani di query e li riutilizza. Durante la compilazione di piani di query, l'hint di query RECOMPILE utilizza i valori correnti di qualsiasi variabile locale nella query e, se la query si trova all'interno di una procedura memorizzata, i valori correnti passano a tutti i parametri.
RECOMPILE è un'utile alternativa alla creazione di una procedura memorizzata che utilizza la clausola WITH RECOMPILE quando è necessario ricompilare solo un sottoinsieme di query all'interno della procedura memorizzata, anziché l'intera procedura memorizzata. Per ulteriori informazioni, consultare Ricompilazione di stored procedure. RICOMPILE è utile anche quando si creano guide di piano. Per ulteriori informazioni, vedere Ottimizzazione delle query nelle applicazioni distribuite utilizzando le guide di piano.
Poiché la mia query ha molte variabili locali, la mia ipotesi è che SQL Server sia in grado di ottimizzarla (seriamente) quando utilizzo il OPTION (RECOMPILE)
suggerimento per la query.
Ovunque guardi la gente dice che OPTION (RECOMPILE)
dovrebbe essere evitato. La spiegazione di ciò è generalmente che l'utilizzo di questo suggerimento SQL Server non è in grado di riutilizzare questo piano di exection e quindi deve perdere tempo a ricompilarlo ogni volta.
(Ma) Dato il gigantesco vantaggio in termini di prestazioni, sono propenso a pensare che usare questo suggerimento per la query questa volta sarebbe una buona cosa.
Dovrei usarlo? In caso contrario, esiste un modo per forzare SQL Server a utilizzare un piano di esecuzione migliore senza questo suggerimento e senza alterare l'applicazione?