2009-07-29 16 views
126

Ho un caso in cui l'utilizzo di un JOIN o un IN mi darà i risultati corretti ... Che in genere ha prestazioni migliori e perché? Quanto dipende da quale server di database si sta eseguendo? (FYI Sto usando MSSQL)SQL JOIN vs IN prestazioni?

+0

Ci scusiamo per l'eventuale dupe ... non ho trovato quella domanda quando stavo cercando – Polaris878

+0

:) In realtà stavo cercando un altro articolo che ho usato quando ho fatto una ricerca in qualcosa di simile qualche tempo fa, e mi sono imbattuto in quello di errore – AdaTheDev

risposta

153

In generale, IN e JOIN sono query diverse che possono produrre risultati diversi.

SELECT a.* 
FROM a 
JOIN b 
ON  a.col = b.col 

non è lo stesso di

SELECT a.* 
FROM a 
WHERE col IN 
     (
     SELECT col 
     FROM b 
     ) 

, a meno che non b.col è unico.

Tuttavia, questo è sinonimo della prima query:

SELECT a.* 
FROM a 
JOIN (
     SELECT DISTINCT col 
     FROM b 
     ) 
ON  b.col = a.col 

Se la colonna giunzione è UNIQUE e contrassegnati come tali, entrambe queste query resa lo stesso piano in SQL Server.

Se non lo è, quindi IN è più veloce di JOIN su DISTINCT.

veda questo articolo nel mio blog per i dettagli delle prestazioni:

+4

Oooh, bella spina :-) – paxdiablo

+0

Sì, ha senso che avrebbero eseguito lo stesso se la colonna di congiunzione è unica (che è nel mio caso) – Polaris878

+1

Su una nota simile, dovrei usare IN (SELECT DISTINCT ...) o semplicemente IN (SELEZIONA ...)? – moo

3

Questo è piuttosto difficile da dire - al fine di scoprire veramente quale funziona meglio, è necessario conoscere i tempi di esecuzione.

Come regola generale, penso che se si hanno indici sulle colonne della chiave esterna e se si utilizzano solo (o principalmente) le condizioni JOIN INTERNO, allora il JOIN sarà leggermente più veloce.

Ma non appena inizi a utilizzare OUTER JOIN, o se ti mancano indici di chiavi esterne, IN potrebbe essere più veloce.

Marc

+0

Stavo pensando anche a questo ... perché sembra JOIN è un caso più comune e sarebbe più probabilmente ottimizzato – Polaris878

23

divertente si menziona che, ho fatto un post sul blog su questo argomento.

veda la risposta Oracle vs MySQL vs SQL Server: Aggregation vs Joins

breve: bisogna testarlo e singoli database variano molto.

+3

Oooh, un'altra bella spina :-) – paxdiablo

+2

Io non sono sopra l'auto-promozione. :) – cletus

+2

@cletus: Sono davvero tentato di registrare in-vs-join-vs-esiste dot com, raccogliere tutti i plug e iniziare a raccogliere soldi: – Quassnoi

1

L'ottimizzatore dovrebbe essere abbastanza intelligente da fornire lo stesso risultato in qualsiasi modo per le query normali. Controlla il piano di esecuzione e dovrebbero darti la stessa cosa. Se non lo fanno, normalmente considererei JOIN più veloce. Tuttavia, tutti i sistemi sono diversi, quindi è necessario profilare il codice sul proprio sistema per essere sicuri.

+3

Dovrebbe essere? Può essere. Lo fa? No. Vedi il mio post. – cletus

3

L'implementazione di ogni database ma probabilmente si può immaginare che risolvono tutti i problemi più o meno nello stesso modo. Se si utilizza MSSQL, dare un'occhiata al piano di esecuzione che viene generato. Puoi farlo attivando i programmi di profiler ed esecuzioni. Questo ti darà una versione di testo quando eseguirai il comando.

Non sono sicuro di quale versione di MSSQL si sta utilizzando, ma è possibile ottenere una versione grafica in SQL Server 2000 nell'analizzatore di query. Sono sicuro che questa funzionalità è in agguato in alcuni casi in SQL Server Studio Manager nelle versioni successive.

Dai un'occhiata al piano di esecuzione. Per quanto possibile, evita scansioni della tabella a meno che, naturalmente, la tua tabella sia piccola, nel qual caso una scansione della tabella è più veloce rispetto all'utilizzo di un indice. Leggi le diverse operazioni di join che ogni scenario produce.

3

Un interessante resoconto interessante sulle differenze logiche: SQL Server: JOIN vs IN vs EXISTS - the logical difference

Sono abbastanza sicuro che supponendo che le relazioni e gli indici sono mantenuti un Join si esibirà complessivamente meglio (più sforzi vengono fatti per lavorare con quell'operazione, poi altri). Se ci pensate concettualmente, allora è la differenza tra 2 query e 1 query.

È necessario collegarlo a Query Analyzer e provare e vedere la differenza. Guarda anche il Query Execution Plan e prova a ridurre i passaggi.

+0

Interessante ..... –

+0

la migliore risposta per me –

2

Questa discussione è piuttosto vecchia, ma viene citata spesso. Per il mio gusto personale è un po 'incompleto, perché c'è un altro modo per chiedere al database la parola chiave EXISTS che ho trovato essere più veloce il più delle volte.

Quindi, se siete interessati solo a valori da tabella A è possibile utilizzare questa query:

SELECT a.* 
FROM a 
WHERE EXISTS (
    SELECT * 
    FROM b 
    WHERE b.col = a.col 
    ) 

La differenza potrebbe essere enorme se col non è indicizzata, in quanto il db non ha bisogno di trovare tutti i record in b che hanno lo stesso valore in col, deve solo trovare il primo. Se non ci sono indici su b.col e molti record in b una scansione di tabella potrebbe essere la conseguenza. Con IN o JOIN questa sarebbe una scansione completa della tabella, con EXISTS questa sarebbe solo una scansione parziale della tabella (finché non verrà trovato il primo record corrispondente).

Se ci sono molti record in b che hanno lo stesso valore di colonna, sprecherai anche molta memoria per leggere tutti questi record in uno spazio temporaneo solo per scoprire che la tua condizione è soddisfatta. Con esiste questo può essere evitato solitamente.

Ho spesso trovato EXISTS più veloce di IN anche se esiste un indice. Dipende dal sistema di database (l'ottimizzatore), i dati e non ultimo ultimo dal tipo di indice che viene utilizzato.

+2

Su MSSql il fatto che esista è meglio di un IN non sembra vero. Per ulteriori informazioni: http://explainextended.com/2009/06/16/in-vs-join-vs-exists/ Qui puoi leggere che: "Molti pensano che EXISTS sia più efficiente di IN, perché EXISTS restituisce solo una riga Questo non è vero per SQL Server Come possiamo vedere dagli esempi sopra, EXISTS e IN produce esattamente gli stessi piani Questo perché EXISTS è più flessibile di IN. Un IN può sempre essere riscritto come ESISTE (usando una semplice condizione WHERE con un equijoin) ma non viceversa. " –