sql >> Databasteknik >  >> RDS >> Mysql

JOIN vs. VAR:Varför uppvisar två frågor som får identiska resultat 3-4 storleksordningar prestandaskillnader?

MySQL har kända problem med optimeringsfrågor som involverar korrelerade delfrågor, eller underval. Fram till version 5.6.5 materialiseras det inte underfrågor, men det kommer att materialiseras en härledd tabell som används i en join.

I huvudsak betyder detta att när du använder en join kommer MySQL att utföra följande första gången underfrågan påträffas:

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

Och behåll resultaten i en tillfällig tabell (som hashas för att göra uppslagningar snabbare), sedan för varje värde i myTable den kommer att slå upp mot den temporära tabellen för att se om koden finns där.

Men sedan när du använder IN underfrågan materialiseras inte och skrivs om 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
    )

Vilket betyder att för varje code i myTable , kör den underfrågan igen. Vilket när din yttre fråga är mycket smal är bra, eftersom det är mer effektivt att bara köra underfrågan ett fåtal gånger, än att köra den för alla värden och lagra resultaten i en temporär tabell, men när din yttre fråga är bred, resulterar det i i den inre frågan som körs många gånger, och det är här prestandaskillnaden börjar.

Så för dina radräkningar, istället för att köra underfrågan ~30 000 gånger, kör du den en gång och slår sedan upp ~30 000 rader mot en hashad temporär tabell med bara 400 rader in. Detta skulle svara för en så drastisk prestandaskillnad.

Den här artikeln i onlinedokumentationen förklarar subquery optimering mycket mer djupgående.




  1. Det gick inte att ladda sqlite-databasen vid första körningen

  2. MySQL GROUP_CONCAT flyktar

  3. oci_bind_by_name och to_date PHP/OCI/Oracle

  4. Formatera siffror med kommatecken i PostgreSQL