2012-06-07 13 views
8

Beh, forse sono troppo vecchia scuola e mi piacerebbe capire quanto segue.Perché un'unione è più veloce di un gruppo di

interrogazione 1.

select count(*), gender from customer 
group by gender 

interrogazione 2.

select count(*), 'M' from customer 
where gender ='M' 
union 
select count(*), 'F' from customer 
where gender ='F' 

la prima domanda è più semplice, ma per qualche ragione nel profiler, quando eseguo entrambi allo stesso tempo, si dice che la query 2 utilizza il 39% delle volte e la query 1, 61%.

Vorrei capire il motivo, forse devo riscrivere tutte le mie domande.

+1

Un'ipotesi: la seconda query non ha in realtà alcuna aggregazione e non viene mantenuto nessuno stato per calcolare i conteggi (è solo il numero di restituzione delle righe corrispondenti per 'count (*)') – lanzz

+0

cosa intendi 'a nello stesso tempo? – Sebas

+2

Suppongo che tu abbia solo 2 sessi e che ognuno abbia un genere assegnato piuttosto che alcuni 'NULL'? Inoltre, cosa succede se provi 'UNION ALL'? Questo migliora ancora di più il secondo? Anche cosa RDBMS e come sono i piani di esecuzione? Anche i costi relativi nei piani di esecuzione di SQL Server non riflettono necessariamente le prestazioni reali se questo è ciò che si utilizza per confrontare le due query. –

risposta

5

La query 2 è in realtà un bel trucco. Funziona così: hai un indice sul genere. Il DBMS può cercare in quell'indice due volte per ottenere due intervalli di righe (uno per M e uno per F). Non ha bisogno di leggere nulla da queste righe, solo che esistono. Può contare il numero di righe esistenti nei due intervalli.

Nella prima query il DBMS deve decodificare le righe per leggere il sesso, quindi deve ordinare le righe o creare una tabella hash per aggregarle. Questo è più costoso del semplice conteggio delle righe.

+0

Un indice su genere potrebbe essere utilizzato anche per un flusso aggregato sulla prima query. Non è richiesto alcun ordinamento poiché sono già nell'ordine dell'indice. –

+0

È vero, tuttavia le righe devono essere decodificate e confrontate l'una con l'altra. – usr

+0

Le righe devono essere decodificate in un indice cercare troppo in modo che sappia quando ha raggiunto l'ultima riga corrispondente al predicato di ricerca e deve interrompere la scansione. –

0

L'ottimizzazione di una query dipende dal database. Quello che stai vedendo è specifico del database.

L'unione, come scritto, richiede ingenuamente due passaggi attraverso i dati, facendo un filtro e un conteggio. Fondamentalmente non è necessario altro spazio di archiviazione.

L'aggregazione può ordinare i dati e quindi eseguire un conteggio. Oppure potrebbe generare una tabella hash. Data la differenza di prestazioni, direi che viene utilizzato un ordinamento. Chiaramente, questo è eccessivo per questo tipo di query.

Se si dispone di un indice di genere, entrambi i metodi sarebbe essenzialmente scansionare l'indice in modo le prestazioni dovrebbero essere simili (la versione unione potrebbe eseguire la scansione = due volte.

Il database che si sta utilizzando offrire un modo per calcolare le statistiche sulle tabelle Se è così, è necessario aggiornare le statistiche e vedere se si ottengono ancora gli stessi risultati

Inoltre, è possibile pubblicare i risultati di "spiegare" o il piano di esecuzione? Ciò spiegherebbe esattamente il motivo per cui si è più veloce dell'altro

2

Sei sicuro? Forse il secondo q uery usa solo risorse in cache dal primo in poi.

eseguirli in due lotti separati e ciascuno di essi esegue DBCC FREEPROCCACHE per pulire la cache. Quindi confrontare i valori di ciascun piano di esecuzione.

+1

Anche questa sarebbe la mia ipotesi – Filip

0

Ho provato una query equivalente, ma ho trovato il risultato opposto; il sindacato ha preso il 65% e il "gruppo per" ha preso il 35%. (Utilizzo di SQL Server 2008). Non ho un indice su genere, quindi il mio piano di esecuzione mostra una scansione indice in cluster. A meno che non si esamini dettagliatamente il piano di esecuzione, non è possibile spiegare questo risultato.

L'aggiunta di un indice per questa query non è probabilmente una buona idea, poiché probabilmente non si eseguirà questa query quasi tutte le volte che si inseriranno i record nella tabella dei clienti. In alcuni altri motori di database con indici bitmap (Oracle, PostgreSQL), il motore del database può combinare più indici, in modo da poter alterare l'utilità degli indici a colonna singola.Ma in SQL Server, è necessario progettare gli indici per "coprire" le query comunemente utilizzate.

Problemi correlati