SQL JOIN vs IN performance?


164

Ho un caso in cui l'utilizzo di JOIN o IN mi darà i risultati corretti ... Che in genere ha prestazioni migliori e perché? Quanto dipende da quale server di database stai eseguendo? (Cordiali saluti sto usando MSSQL)


:) In realtà stavo cercando un articolo diverso che ho usato quando ho cercato qualcosa di simile qualche tempo fa e mi sono imbattuto in quello per errore
AdaTheDev

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

Risposte:


197

In generale, INe JOINsono 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.colsia unico.

Tuttavia, questo è il sinonimo della prima query:

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

Se la colonna di join è UNIQUEe contrassegnata come tale, entrambe queste query generano lo stesso piano SQL Server.

In caso contrario, INè più veloce di JOINacceso DISTINCT.

Vedi questo articolo nel mio blog per i dettagli sulle prestazioni:


Sì, ha senso che eseguiranno lo stesso se la colonna di
join

1
In una nota simile, dovrei usare IN (SELECT DISTINCT ...) o semplicemente IN (SELECT ...)?
moo,

8
@ orlandu63: INimplica DISTINCT. SQL Serverè abbastanza intelligente da accorgersene e genererà gli stessi piani per entrambe le query. Non sono sicuro, tuttavia, come RDBMSsi comporteranno gli altri.
Quassnoi,

>> IN e JOIN sono query diverse che possono produrre risultati diversi. Puoi spiegare perché in questo caso genererebbe risultati diversi anche se b.col non è unico?
Abhijeet,



6

È piuttosto difficile da dire - per scoprire davvero quale funziona meglio, devi effettivamente profilare i tempi di esecuzione.

Come regola generale, penso che se hai indici sulle colonne della chiave esterna e se stai utilizzando solo (o principalmente) le condizioni INNER JOIN, allora JOIN sarà leggermente più veloce.

Ma non appena si inizia a utilizzare OUTER JOIN o se mancano gli indici di chiave esterna, IN potrebbe essere più veloce.

Marc


Lo stavo pensando anch'io ... perché sembra che JOIN sia un caso più comune e che molto probabilmente verrebbe ottimizzato
Polaris878,

4

Un interessante resoconto delle differenze logiche: SQL Server: JOIN vs IN vs EXISTS - la differenza logica

Sono abbastanza sicuro che supponendo che le relazioni e gli indici siano mantenuti, un Join funzionerà meglio nel complesso (più sforzi ci sono nel lavorare con quell'operazione di altri). Se ci pensi concettualmente, allora è la differenza tra 2 query e 1 query.

Devi collegarlo a Query Analyzer e provarlo e vedere la differenza. Guarda anche il Piano di esecuzione delle query e cerca di ridurre al minimo i passaggi.


4

Questo thread è piuttosto vecchio ma ancora menzionato spesso. Per i miei gusti personali è un po 'incompleto, perché esiste un altro modo per chiedere al database con la parola chiave EXISTS che ho trovato più veloce il più delle volte.

Quindi se sei interessato solo ai valori della tabella a puoi usare questa query:

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

La differenza potrebbe essere enorme se col non è indicizzato, perché il db non deve trovare tutti i record in b che hanno lo stesso valore in col, deve solo trovare il primo. Se non vi è alcun indice su b.col e molti record nella scansione della tabella ba potrebbero essere la conseguenza. Con IN o JOIN si tratterebbe di una scansione completa della tabella, con EXISTS sarebbe solo una scansione parziale della tabella (fino a quando non viene trovato il primo record corrispondente).

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

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


3
Su MSSql il fatto che esista è migliore di un IN non sembra vero. Per maggiori informazioni: spieginextended.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 precedenti, EXISTS e IN producono esattamente gli stessi piani. Questo perché EXISTS è più flessibile di IN. Un IN può sempre essere riscritto come EXISTS (usando una semplice condizione WHERE con un equijoin ) ma non viceversa ".
Micaël Félix

3

L'implementazione di ogni database, ma probabilmente si può immaginare che risolvano tutti i problemi più o meno allo stesso modo. Se stai usando MSSQL dai un'occhiata al piano di esecuzione che viene generato. Puoi farlo attivando il profiler e i piani di esecuzione. Questo ti darà una versione di testo quando esegui il comando.

Non sono sicuro di quale versione di MSSQL stai utilizzando, ma puoi ottenerne una 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 espirazione. Per quanto possibile, evitare le scansioni delle tabelle a meno che, naturalmente, la tabella non sia piccola, nel qual caso una scansione delle tabelle è più veloce dell'uso di un indice. Leggi le diverse operazioni di join prodotte da ogni diverso scenario.


1

L'ottimizzatore dovrebbe essere abbastanza intelligente da darti lo stesso risultato in entrambi i modi per le normali query. Controlla il piano di esecuzione e dovrebbero darti la stessa cosa. In caso contrario, normalmente considererei il JOIN più veloce. Tutti i sistemi sono diversi, tuttavia, quindi è necessario profilare il codice sul proprio sistema per essere sicuri.


5
Dovresti ... dovrebbe? Può essere. Vero? No. Vedi il mio post.
cletus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.