OPTION FORCE ORDER migliora le prestazioni fino all'eliminazione delle righe


9

Ho una query un po 'complessa di SQL Server 2008 (circa 200 righe di SQL abbastanza denso) che non funzionava come avevo bisogno. Nel tempo, le prestazioni sono diminuite da circa 0,5 secondi a circa 2 secondi.

Dando un'occhiata al piano di esecuzione, era abbastanza ovvio che riordinando i join, le prestazioni potevano essere migliorate. L'ho fatto e lo ha fatto ... fino a circa 0,3 secondi. Ora la query ha il suggerimento "OPTION FORCE ORDER" e la vita è buona.

Mi accompagna oggi, ripulendo il database. Archivo circa il 20% delle righe, non eseguendo alcuna azione nel database pertinente tranne l'eliminazione delle righe ... il piano di esecuzione viene TOTALMENTE cancellato . Valuta completamente il numero di righe restituite da alcuni sottotitoli e (ad esempio) sostituisce a:

<Hash>

con

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

Ora il tempo di query aumenta da circa 0,3 secondi a circa 18 secondi. (!) Solo perché ho eliminato le righe. Se rimuovo il suggerimento per la query, torno al tempo di query di circa 2 secondi. Meglio, ma peggio.

Ho riprodotto il problema dopo aver ripristinato il database in più posizioni e server. La semplice eliminazione di circa il 20% delle righe da ogni tabella causa sempre questo problema.

  1. È normale che un ordine di join forzato renda le stime della query completamente imprecise (e quindi tempi di query imprevedibili)?
  2. Dovrei semplicemente aspettarmi che dovrò accettare prestazioni di query non ottimali o guardarlo come un falco e modificare frequentemente manualmente i suggerimenti per le query? O forse accenni anche a ogni join? .3s a 2s è un grande successo da prendere.
  3. È ovvio perché l'ottimizzatore è esploso dopo aver eliminato le righe? Ad esempio, "sì, è stata eseguita una scansione di esempio e poiché ho archiviato la maggior parte delle righe in precedenza nella cronologia dei dati, l'esempio ha prodotto risultati scarsi, quindi ha sottovalutato la necessità di un'operazione di hash ordinata"?

Se desideri vedere i piani di esecuzione, ti preghiamo di suggerire un luogo in cui posso pubblicarli. Altrimenti, ho provato il bit più sorprendente. Ecco la stima errata fondamentale, i numeri tra parentesi sono (stimati: effettivi) righe.

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

Si noti che il ciclo interno dovrebbe scansionare 908 righe, ma scansiona invece 52.258.441. Se fosse stato accurato, questo ramo avrebbe funzionato per circa 2ms, anziché 12sec. Prima di eliminare le righe, questa stima del join interno era disattivata solo per un fattore totale di 2 ed è stata eseguita come corrispondenza hash su due indici cluster.

Risposte:


6

È normale che un ordine di join forzato renda le stime della query completamente imprecise (e quindi tempi di query imprevedibili)?

L'uso di FORCE ORDER non rende inaccurate le stime, come ha fatto l'eliminazione delle righe. Forzare un aggiornamento delle statistiche sulla tabella può migliorare l'accuratezza della stima.

Dovrei semplicemente aspettarmi che dovrò accettare prestazioni di query non ottimali o guardarlo come un falco e modificare frequentemente manualmente i suggerimenti per le query? O forse accenni anche a ogni join? .3s a 2s è un grande successo da prendere.

Preferibile sarebbe garantire all'ottimizzatore le informazioni necessarie per generare il piano migliore, senza utilizzare il suggerimento FORCE ORDER. In tal modo, dovrebbe affrontare meglio le modifiche alla distribuzione dei dati sottostanti senza richiedere l'intervento manuale. Detto questo, se la natura dei dati è tale che la cardinalità può variare in modo significativo ora per ora o giorno per ora, prendere in considerazione l'uso di una guida di piano per assicurarsi che il piano sia corretto.

È ovvio perché l'ottimizzatore è esploso dopo aver eliminato le righe? Ad esempio, "sì, è stata eseguita una scansione di esempio e poiché ho archiviato la maggior parte delle righe in precedenza nella cronologia dei dati, l'esempio ha prodotto risultati scarsi, quindi ha sottovalutato la necessità di un'operazione di hash ordinata"?

Non hai menzionato i conteggi delle righe nelle tabelle dei problemi, ma è probabile che le eliminazioni:

  • non ha rimosso abbastanza righe per attivare un aggiornamento delle statistiche. Ciò dovrebbe verificarsi quando il 20% delle righe è stato modificato, ma esiste l'opzione per utilizzare il flag di traccia 2371 per abilitare una soglia dinamica.
  • ha attivato un aggiornamento delle statistiche ma il campione raccolto non era rappresentativo. Correggere eseguendo un aggiornamento manuale WITH FULLSCAN .

Potresti anche imbatterti in problemi di sniffing dei parametri vecchio stile , per i quali ci sono una miriade di opzioni su cui aggirare. WITH RECOMPILE potrebbe essere un'opzione costosa da specificare con una query di dimensioni così grandi, ma vale la pena indagare sia a livello di procedura che di istruzione.


Solo un chiarimento, probabilmente è la semantica: "L'uso di FORCE ORDER non sta rendendo imprecise le stime, lo ha fatto la cancellazione delle righe". Quindi pensi che sia solo una possibilità casuale che la rimozione di "FORCE ORDER" abbia migliorato così tanto la query? Il suggerimento non ha spinto l'ottimizzatore a fare affidamento su statistiche su cui avrebbe preferito porre meno enfasi, o non è stato scoperto nel test dell'applicazione perché questa statistica meno affidabile era raramente fondamentale?
Shannon,

Penso di sì, in quanto gli ottimizzatori hanno preferito la scelta del piano per far fronte alle statistiche imprecise, ma il piano derivante dall'ordine di join forzato non lo fa. Non sono a conoscenza del fatto che FORCE ORDER abbia causato cambiamenti nella valutazione delle statistiche, qualcun altro interverrà se saprà qualcosa di contrario. Inoltre, devi considerare se il valore che hai scelto di OTTIMIZZARE È appropriato. Le statistiche potrebbero andare benissimo ma stai forzando un piano basato su un valore non rappresentativo.
Mark Storey-Smith,

Giusto. Ho lo stesso problema di prestazioni passando i parametri esattamente come li ho ottimizzati. Grazie ancora.
Shannon,
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.