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

JOIN vs. HVOR:Hvorfor udviser to forespørgsler, der opnår identiske resultater, en præstationsforskel på 3-4 størrelsesordener?

MySQL har kendte problemer med optimeringsforespørgsler, der involverer korrelerede underforespørgsler eller undervalg. Indtil version 5.6.5 materialiserer det ikke underforespørgsler, men det vil materialisere en afledt tabel, der bruges i en join.

I bund og grund betyder dette, at når du bruger en joinforbindelse, vil MySQL udføre følgende første gang underforespørgslen stødes på:

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

Og hold resultaterne i en midlertidig tabel (som er hashed for at gøre opslag hurtigere) og derefter for hver værdi i myTable den vil slå op mod den midlertidige tabel for at se, om koden er der.

Men siden da bruger du IN underforespørgslen er ikke materialiseret og er omskrevet som:

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
    )

Hvilket betyder, at for hver code i myTable , kører den underforespørgslen igen. Hvilket når din ydre forespørgsel er meget smal er fint, da det er mere effektivt kun at køre underforespørgslen et par gange, end at køre den for alle værdier og gemme resultaterne i en midlertidig tabel, men når din ydre forespørgsel er bred, resulterer det i i den indre forespørgsel, der udføres mange gange, og det er her, præstationsforskellen starter.

Så for dine rækketællinger, i stedet for at køre underforespørgslen ~30.000 gange, kører du den én gang og slår derefter ~30.000 rækker op mod en hashed midlertidig tabel med kun 400 rækker i. Dette ville tage højde for en så drastisk forskel i ydeevne.

Denne artikel i onlinedokumenterne forklarer optimering af underforespørgsler i meget mere dybde.




  1. SQL Server Transactional Replication Configuration

  2. udarbejdet erklæring, hvor værdien er i matrix

  3. Opret en funktion med valgfri argumenter i MySQL

  4. MySQL-udløser før Indsæt værdikontrol