Domanda

Sono curioso quale delle seguenti sotto sarebbe più efficace?

Sono sempre stato un po 'cauto sull'utilizzo IN perché credo SQL Server trasforma il set di risultati in una grande dichiarazione IF. Per un grande set di risultati, questo potrebbe compromettere le prestazioni. Per i piccoli set di risultati, non sono sicuro neanche è preferibile. Per i grandi set di risultati, non sarebbe EXISTS essere più efficiente?

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

vs.

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
È stato utile?

Soluzione

EXISTS sarà più veloce perché una volta che il motore ha trovato un colpo, si annullerà cercando, come la condizione è dimostrato vero.

Con IN, raccoglierà tutti i risultati della sub-query prima di ulteriori trasformazioni.

Altri suggerimenti

La risposta accettata è miope e la questione un po 'allentato in che:

  

1) Né esplicitamente menzionato se un indice di rivestimento è presente in   sinistra, a destra, o entrambe le parti.

     

2) Né tiene conto delle dimensioni di ingresso destro set lato e   ingresso di impostazione lato destro.
        (La domanda cita un solo grande risultato complessivo set).

Credo che l'ottimizzatore è abbastanza intelligente per la conversione tra "in" vs "esiste" quando v'è una differenza di costo significativa a causa di (1) e (2), altrimenti si può solo essere usato come un suggerimento (ad esempio, esiste per incoraggiare l'uso di un un indice ricercabile sul lato destro).

Entrambe le forme possono essere convertiti per unire forme internamente, hanno l'ordine di join invertito, e corrono come loop, hash o unione - in base ai conteggi stimati fila (sinistro e destro) e indice di esistenza nella sinistra, a destra, o entrambi i lati.

Ho fatto alcuni test su SQL Server 2005 e 2008, e sia sul esiste e il IN tornare con lo stesso identico piano di esecuzione vera e propria, come altri hanno detto. Optimizer è ottimale. :)

Qualcosa di essere a conoscenza, però, ESISTE, IN, e si uniscono a volte può restituire risultati diversi se non la query frase giusto: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

mi piacerebbe andare con ESISTE IN sopra, vedi sotto link:

SQL Server: ENTRA IN vs vs ESISTE - la logica differenza

I piani di esecuzione sono in genere sta per essere identico in questi casi, ma fino a quando non vedere come i fattori Optimizer in tutti gli altri aspetti di indici, ecc, è davvero saprà mai.

Quindi, in non è lo stesso di ESISTE né produrrà lo stesso piano di esecuzione.

Di solito esiste è utilizzata in una subquery correlata, che significa che si unirà al EXISTS query interna con la query esterna. Che aggiungere ulteriori passi per produrre un risultato di cui hai bisogno per risolvere la query outer join e query interna si unisce poi corrisponde loro in cui le clausole di unirsi sia.

Solitamente IN viene utilizzato senza correlando query interna con query esterna, e che può essere risolto in un solo stadio (nel migliore dei casi).

Considerate questo:

  1. Se si utilizza IN e il risultato della query interna viene milioni di righe di valori distinti, sarà probabilmente eseguire più lento di EXISTS dato che il EXISTS query è performante (ha gli indici diritto di aderire con la query esterna).

  2. Se si utilizza esiste e il join con la query esterna è complessa (richiede più tempo per eseguire, senza opportuni indici) che rallenterà la query per il numero di righe della tabella esterna, a volte il tempo stimato per completo può essere in giorni. Se il numero di righe è accettabile per la vostra data hardware o la cardinalità dei dati è corretta (ad esempio meno valori distinti in un grande insieme di dati) IN in grado di eseguire più velocemente di quanto esiste.

  3. Tutto quanto sopra si noterà quando si dispone di una discreta quantità di righe su ogni tavolo (da fiera intendo qualcosa che supera la vostra elaborazione della CPU e / o soglie di RAM per la memorizzazione nella cache).

Quindi la risposta è dipende. È possibile scrivere una query complessa all'interno IN o esiste, ma come regola generale, si dovrebbe cercare di utilizzare IN con un insieme limitato di valori distinti ed esiste quando si hanno un sacco di righe con un sacco di valori distinti.

Il trucco è quello di limitare il numero di righe da sottoporre a scansione.

Saluti,

MarianoC

Per ottimizzare la EXISTS, essere molto letterale; qualcosa deve solo essere lì, ma in realtà non ha bisogno di dati restituiti dal correlato sub-query. Stai solo la valutazione di una condizione booleana.

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

Poiché il correlato sub-query è RBAR, il colpo primo risultato rende la condizione vera, e viene elaborato oltre.

Ci sono molte risposte fuorvianti risposte qui, compreso quello altamente upvoted (anche se non credo che i loro ops significava danno). La risposta breve è: Questi sono gli stessi

.

Ci sono molte parole chiave nel (T) linguaggio SQL, ma alla fine, l'unica cosa che realmente accade sul hardware è le operazioni come si vede nel piano di query di esecuzione.

L'operazione relazionale (teoria matematica) che facciamo quando invochiamo [NOT] IN e [NOT] EXISTS è il semi uniscono (anti-join quando si utilizza NOT). Non è un caso che le operazioni di corrispondente sql-server hanno lo stesso nome . Non v'è alcuna operazione che cita IN o EXISTS ovunque - solo (anti) semi unisce. Così, non c'è modo che un IN logicamente equivalente vs scelta EXISTS potrebbe influire sulle prestazioni perché non v'è un solo modo, la (anti) semi unirsi operazione di esecuzione, per ottenere i loro risultati .

Un esempio:

Interrogazione 1 ( piano )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

Interrogazione 2 ( piano )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

Al largo della parte superiore della mia testa e non garantisce che sia esatto: Credo che la seconda sarà più veloce in questo caso.

  1. Nella prima, la subquery correlata probabilmente causerà la sottoquery da eseguire per ogni riga.
  2. Nel secondo esempio, la subquery deve essere eseguito solo una volta, poiché non correlata.
  3. Nel secondo esempio, il IN si corto circuito appena trova una corrispondenza.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top