Come ottimizzare due query che usano UNION?

lunedì 05 ottobre 2009 - 09.51

paquito_ita Profilo | Senior Member

Salve,

ho riunito in un'unica query due SELECT distinte che reperiscono record di tipo "Todo" e "Personal Contributions" (questi ultimi sono un caso speciale di todo). Al momento, per ragioni tempistiche, ho unito le due query con una UNION. Tuttavia il risultato benchè corretto, non è di certo molto efficiente.
Ho iniziato a considerare l'ipostesi di usare CASE WHEN THEN, ma mi sono presto ingarbugliato, per il fatto che in alcuni casi (ad esempio ActivitySpace.Title in Personal Contributions) devo reperire il valore da un campo piuttosto che usare un semplice valore statico.

Mi sapreste consigliare (se possibile con un esempio), come ottimizzare la query? Utilizzo SQL Server 2008.
Grazie
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

lbenaglia Profilo | Guru

>ho riunito in un'unica query due SELECT distinte che reperiscono
>record di tipo "Todo" e "Personal Contributions" (questi ultimi
>sono un caso speciale di todo). Al momento, per ragioni tempistiche,
>ho unito le due query con una UNION. Tuttavia il risultato benchè
>corretto, non è di certo molto efficiente.

Ciao Luca,

Per quanto riguarda l'operatore UNION se non ti importa eliminare eventuali righe duplicate puoi specificare l'opzione ALL in modo da evitare tale verifica.
Per quanto riguarda le singole query prova a sostituire l'operatore IN con EXISTS oppure utilizza una outer qurery.

>Grazie
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

paquito_ita Profilo | Senior Member

Ciao Lorenzo,

grazie per il suggerimento. Tuttavia il mio timore è che pur sostituendo EXIST a IN vi saranno problemi in termini di efficienza, quando i record interessati diventeranno centinaia di migliaia o più. La seconda query è un superset dei record selezionati dalla prima, infatti escludo dalla 2° query i record ottenuti dalla 1° in modo da ottenere i Todo che non siano Contributions.
Quindi l'ideale sarebbe per me poter avere un'unica query e impostare i valori restituiti dalla SELECT relativamente alla tipologia di record (se cioè Todo o Contribution).
Pensi sia fattibile?
Grazie di nuovo

lbenaglia Profilo | Guru

>grazie per il suggerimento. Tuttavia il mio timore è che pur
>sostituendo EXIST a IN vi saranno problemi in termini di efficienza,
>quando i record interessati diventeranno centinaia di migliaia
>o più.
Perché? Il numero di righe è invariante.
EXISTS è decisamente più efficiente rispetto a IN (che viene tradotta dal query optimizer in tante condizioni di OR).

La seconda query è un superset dei record selezionati
>dalla prima, infatti escludo dalla 2° query i record ottenuti
>dalla 1° in modo da ottenere i Todo che non siano Contributions.
>Quindi l'ideale sarebbe per me poter avere un'unica query e impostare
>i valori restituiti dalla SELECT relativamente alla tipologia
>di record (se cioè Todo o Contribution).
>Pensi sia fattibile?
Non lo so. Posta un esempio completo con i comandi di CREATE TABLE, alcune righe di prova (INSERT INTO) ed il result set finale che vorresti ottenere con quei dati.

>Grazie di nuovo
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5