2009-10-07 10 views
12

Ho una query complessa che ho bisogno di utilizzare in una query successiva (in realtà la dichiarazione di aggiornamento). Ho provato ad usare sia un CTE che un tavolo temporaneo. Le prestazioni utilizzando il CTE sono orribili rispetto all'approccio alla tabella temporanea. È qualcosa come 15 secondi vs millisecondi. Per semplificare il test invece di unire la tabella CTE/Temp nella query successiva, ho semplicemente selezionato * da esso. In tal caso, eseguono lo stesso.Tabella SQL 2005 CTE vs TEMP Prestazioni quando utilizzato in join di altre tabelle

Ho esaminato il piano di esecuzione per entrambi gli approcci entrambi con i join nella query successiva e quindi semplicemente selezionare *. Con la semplice selezione i piani di query sono quasi gli stessi, ma con i join nella successiva selezionare i piani di query non lo sono. In particolare, la parte del piano di query per la creazione e il popolamento della tabella temporanea rimane invariata, mentre la parte del piano di query per la creazione e la compilazione del CTE cambia radicalmente quando viene successivamente utilizzata in una query con un join.

La mia domanda è perché il piano di query per la creazione e la popolazione del CTE cambia in base a come viene successivamente utilizzato mentre la tabella temporanea non lo è. Anche in quali scenari, quindi, un CTE produrrà prestazioni migliori rispetto a un tavolo temporaneo?

* Nota Ho utilizzato anche una variabile di tabella ed è paragonabile all'approccio alla tabella temporanea.

Grazie

risposta

9

Stai facendo una domanda complicata, quindi stai ricevendo una risposta complicata: dipende. (Odio quella risposta).

Seriamente, tuttavia, ha a che fare con il modo in cui l'ottimizzatore sceglie un piano dati (che già conoscevi); una tabella temporanea o una variabile è come una struttura permanente in quanto un piano di esecuzione eseguirà l'operazione associata a riempire prima quella struttura e quindi utilizzare quella struttura nelle operazioni successive. Un CTE NON è una tabella temporanea; l'utilizzo del CTE non viene calcolato fino a quando non viene utilizzato dalle operazioni successive e in modo che l'utilizzo influenzi l'ottimizzazione del piano.

Le CTE sono state implementate per problemi di riutilizzabilità e manutenzione, non necessariamente prestazioni; tuttavia, in molti casi (come la ricorsione), si comportano meglio dei metodi di codifica tradizionali.

13

CTE è solo un alias per la query.

Si può (o non può) essere rieseguito ogni volta che viene utilizzato.

Non c'è modo pulito per forzare CTE materializzazione in SQL Server (come Oracle di /*+ MATERIALIZE */), e devi fare i trucchi sporchi in questo modo:

CTE può migliorare le prestazioni se usato nei piani che richiedono solo una valutazione (come HASH JOIN, MERGE JOIN ecc.).

In questi scenari, la tabella hash verrà creata a partire da CTE, mentre l'utilizzo della tabella temporanea richiederà la valutazione dello CTE, l'estrazione dei risultati nella tabella temporanea e la lettura della tabella temporanea ancora una volta.

+1

Sì per materializzare! Un PK/IX nella definizione potrebbe essere carino. – crokusek

2

Trovo che in genere un CTE ripetuto non ottenga miglioramenti delle prestazioni.

Ad esempio, se si utilizza un CTE per popolare una tabella e quindi lo stesso CTE per partecipare a una query successiva, nessun vantaggio. Sfortunatamente, le CTE non sono istantanee e devono essere ripetute per essere utilizzate in due dichiarazioni separate, quindi tendono ad essere valutate due volte.

Invece di CTE, utilizzo spesso i TVF in linea (che possono contenere CTE), che consente un corretto riutilizzo e non sono migliori o peggiori dei CTE nei miei SP.

Inoltre, trovo che il piano di esecuzione può essere negativo se il primo passaggio modifica le statistiche in modo tale che il piano di esecuzione per il secondo passaggio sia sempre impreciso poiché viene valutato prima dell'esecuzione di qualsiasi passaggio.

In questo caso, guardo manualmente la memorizzazione dei risultati intermedi, assicurando che siano indicizzati correttamente e dividendo il processo in più SP e aggiungendo WITH RECOMPILE per assicurare che i successivi SP abbiano piani che siano buoni per i dati che sono in realtà andando a operare.

0

Ho provato a creare CTE con semplice selezionato con filtro dal grande tavolo Quindi 3 volte il subquisito.

Successivamente, fare lo stesso con le tabelle temporanee.

Il risultato è stato del 70% in termini di tempo per CTE -30% che richiede tempo per la tabella temporanea. Quindi la tabella temp è migliore per tali soluzioni.

Non penso che CTE crei una tabella temporanea solo con la query selezionata, ma 3 volte effettui la selezione su una grande tabella.

Problemi correlati