2015-11-11 16 views
6

Dove sto lavorando Mi è stato recentemente detto che l'utilizzo distinto delle query è un brutto segno di un programmatore. Quindi mi chiedo, immagino, che l'unico modo per non utilizzare questa funzione è quello di utilizzare un gruppo entro il.Devo usare distinto nelle mie query

Era a mia conoscenza che la funzione distinta funzioni in modo molto simile a un gruppo tranne che in come è stata letta. Una funzione distinta controlla ogni singolo criterio di selezione rispetto a un gruppo con il quale fa la stessa cosa solo nel suo complesso.

Tenere presente che faccio solo segnalazione. Non creo/altero i dati. Quindi la mia domanda è per le migliori pratiche dovrei usare distinti o di gruppo. Se nessuna delle due esiste un'alternativa. Forse il gruppo dovrebbe essere usato in query più complesse del mio esempio non reale qui, ma tu hai l'idea. Non riuscivo a trovare una risposta che in realtà ha spiegato perché o perché non dovrei usare distinti nelle mie query

select distinct 
    spriden_user_id as "ID", 
    spriden_last_name as "last", 
    spriden_first_name as "first", 
    spriden_mi_name as "MI", 
    spraddr_street_line1 as "Street", 
    spraddr_street_line2 as "Street2", 
    spraddr_city as "city", 
    spraddr_stat_code as "State", 
    spraddr_zip as "zip" 
from spriden, spraddr 
where spriden_user_id = spraddr_id 
and spraddr_mail_type = 'MA' 

VS

select 
    spriden_user_id as "ID", 
    spriden_last_name as "last", 
    spriden_first_name as "first", 
    spriden_mi_name as "MI", 
    spraddr_street_line1 as "Street", 
    spraddr_street_line2 as "Street2", 
    spraddr_city as "city", 
    spraddr_stat_code as "State", 
    spraddr_zip as "zip" 
from spriden, spraddr 
where spriden_user_id = spraddr_id 
and spraddr_mail_type = 'MA' 
group by "ID","last","first","MI","Street","Street2","city","State","zip"  
+8

I due sono praticamente equivalenti. Se stai migliorando le tue abilità SQL, impara ad usare clausole 'JOIN' esplicite. Non usare mai le virgole nella clausola 'from'. –

+3

L'uso di 'DISTINCT' nella query quando si intende ottenere informazioni distinte è una buona indicazione di un programmatore che utilizza il buon senso. La cosa divertente del buon senso è che non è così comune. – zedfoxus

+1

Come menzionato in alcune delle risposte, 'DISTINCT' (e talvolta largo' GROUP BY's) spesso viene usato quando qualcuno non ha completamente compreso il datamodel, e desidera evitare i duplicati - che di solito sono meglio trattati in un altro modo (join più restrittivi, pre-aggregazione o altro). In generale, se tutto ciò che stai cercando di rendere distinto è più ampio delle tue chiavi di indice (> 3-5 colonne), o le colonne non sono su un indice, spesso c'è un modo migliore. –

risposta

11

I database sono intelligente da riconoscere quello che vuoi dire. Mi aspetto che entrambe le tue query funzionino allo stesso modo. È importante che qualcun altro mantenga la tua domanda per sapere cosa intendi. Se davvero intendevi recuperare record distinti, usa DISTINCT. Se la tua intenzione era di fare aggregazione, usa GROUP BY

Dai uno sguardo allo this question. Ci sono alcune belle risposte che potrebbero aiutare.

+0

Questo mi dà alcune informazioni aggiuntive sull'argomento. Vorrei averlo trovato in precedenza. Grazie! –

3

Nell'esempio distinct e group by fare la stessa cosa. Penso che i tuoi colleghi significhi che la tua query non dovrebbe restituire duplicati in prima istanza e che dovresti essere in grado di scrivere la tua query senza una clausola distinct o group by. Potresti essere in grado di ridurre i duplicati estendendo le tue condizioni join.

4

Chiedi loro perché è una cattiva pratica. Molte persone inventano regole o escogitano cose che considerano cattive pratiche leggendo la prima pagina del libro o il primo risultato di una ricerca su google. Se fa il lavoro e non causa problemi, non c'è motivo di creare più lavoro trovando alternative. Tra le due opzioni che ho postato vorrei usare anche distinte perché è più breve e più facile da leggere e mantenere.

+0

haha ​​se solo potessi esprimere quell'opinione come tale –

+0

Penso che sia stato cattivo ma con il nuovo oracle optimizer è abbastanza intelligente da realizzare quello che vuoi. –

+0

': thums_up' Ma è sempre importante dubitare delle proprie azioni, migliorare. – candlejack

4

La risposta fornita da @zedfoxus è utile per comprendere il contesto.

Tuttavia, non credo che la query richieda record distinti se i dati sono stati progettati correttamente.

Sembra che si stia selezionando la chiave primaria della tabella spriden, quindi tutti i dati devono essere univoci. Stai anche entrando nel tavolo spraddr; la tabella contiene davvero dati duplicati validi? O c'è forse un ulteriore criterio di adesione che è necessario per filtrare quei duplicati?

Per questo mi innervosisco circa l'uso di "distinct" - il tavolo spraddr può includere colonne aggiuntive che si dovrebbe utilizzare per filtrare i dati, e "distinct" può essere nascosto che.

Inoltre, è possibile che si stia generando un enorme set di risultati che deve essere filtrato dalla clausola "distinta", che può causare problemi di prestazioni.Ad esempio, se ci sono 1 milione di righe in spraddr per ogni riga in spriden, dovresti utilizzare il flag "is_current" per trovare le 2 o 3 "reali".

Infine, mi innervosisco quando vedo "group by" usato come sostituto per distinto, non perché è "sbagliato", ma perché stilisticamente, credo che group by debba essere usato per funzioni aggregate. Questa è solo una preferenza personale.

+0

Questa risposta è davvero bella; ci vuole un passo indietro per riflettere: perché abbiamo duplicati? – zedfoxus

0

A condizione che le vostre domande siano corrette, DISTINCT e GROUP BY forniscono lo stesso insieme di risultati, ma i vostri colleghi hanno ragione nell'affermare che DISTINCT nasconde dei problemi. Se ti manca un join e utilizzi GROUP BY, riceverai più informazioni di quelle che ti aspetti. Se manca un join e si utilizza DISTINCT, il motore SQL eseguirà un join illimitato (o parzialmente limitato), restringerà i risultati verso il basso e quindi fornirà la risposta prevista.

Oltre all'evidente degrado delle prestazioni nel generare più dati del necessario, si rischia anche di riempire il proprio tempdb (ad es .: esaurendo la stanza sul disco rigido in cui vive il vostro tempdb).

Utilizzare GROUP BY in produzione.

Problemi correlati