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

JOIN vs. DOVE:perché due query che ottengono risultati identici mostrano una differenza di prestazioni di 3-4 ordini di grandezza?

MySQL ha problemi noti con l'ottimizzazione delle query che coinvolgono sottoquery correlate o subselect. Fino alla versione 5.6.5 non materializza le sottoquery, tuttavia materializza una tabella derivata utilizzata in un join.

In sostanza ciò significa che quando si utilizza un join, la prima volta che viene incontrata la sottoquery MySQL eseguirà quanto segue:

SELECT code1 FROM myTable GROUP BY code1 HAVING COUNT(code1) > 1

E mantieni i risultati in una tabella temporanea (che è sottoposta a hash per rendere le ricerche più veloci), quindi per ogni valore in myTable cercherà nella tabella temporanea per vedere se il codice è presente.

Tuttavia, da quando usi IN la sottoquery non viene materializzata e viene riscritta come:

SELECT t1.code1, t1.code2
FROM myTable t1
WHERE EXISTS
    (   SELECT t2.code1 
        FROM myTable t2
        WHERE t2.Code1 = t1.Code1
        GROUP BY t2.code1 
        HAVING COUNT(t2.code1) > 1
    )

Ciò significa che per ogni code in myTable , esegue nuovamente la sottoquery. Che quando la tua query esterna è molto stretta va bene, poiché è più efficiente eseguire la sottoquery solo poche volte, piuttosto che eseguirla per tutti i valori e archiviare i risultati in una tabella temporanea, tuttavia quando la tua query esterna è ampia, risulta nella query interna in esecuzione molte volte, ed è qui che entra in gioco la differenza di prestazioni.

Quindi, per il conteggio delle righe, invece di eseguire la sottoquery circa 30.000 volte, la esegui una volta, quindi cerca circa 30.000 righe in una tabella temporanea con hash con solo 400 righe. Ciò spiegherebbe una differenza di prestazioni così drastica.

Questo articolo nei documenti online spiega l'ottimizzazione delle sottoquery in modo molto più approfondito.