Mysql
 sql >> Database >  >> RDS >> Mysql

Mysql esiste vs IN -- subquery correlato vs subquery?

Questa è una risposta indipendente da RDBMS, ma può comunque aiutare. A mio avviso, la subquery correlata (aka dipendente) è forse il colpevole più spesso falsamente accusato di prestazioni scadenti.

Il problema (come viene spesso descritto) è che elabora la query interna per ogni riga della query esterna. Pertanto, se la query esterna restituisce 1.000 righe e la query interna restituisce 10.000, la query deve scorrere 10.000.000 di righe (esterno × interno) per produrre un risultato. Rispetto alle 11.000 righe (esterna+interna) di una query non correlata sugli stessi set di risultati, non va bene.

Tuttavia, questo è solo lo scenario peggiore. In molti casi, il DBMS sarà in grado di sfruttare gli indici per ridurre drasticamente il numero di righe. Anche se solo la query interna può utilizzare un indice, le 10.000 righe diventano ~13 ricerche, il che riduce il totale a 13.000.

Il exists l'operatore può interrompere l'elaborazione delle righe successive alla prima, riducendo ulteriormente il costo della query, soprattutto quando la maggior parte delle righe esterne corrisponde ad almeno una riga interna.

In alcuni rari casi, ho visto SQL Server 2008R2 ottimizzare le sottoquery correlate a un merge join (che attraversa entrambi i set solo una volta - il miglior scenario possibile) in cui è possibile trovare un indice adatto sia nelle query interne che in quelle esterne.

Il vero colpevole di prestazioni scadenti non sono necessariamente le sottoquery correlate , ma scansioni nidificate .