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

Hvorfor er denne mysql-forespørgsel (med er null-check) så langsommere end denne anden?

Jeg er overrasket over, at enten er hurtigt. Jeg vil foreslå at erstatte dem med exists :

SELECT COUNT(*)
FROM ips_usuario u  
WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
      EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id);

Og for det andet:

SELECT COUNT(*)
FROM ips_usuario u  
WHERE EXISTS (SELECT 1 FROM ips_fatura f WHERE u.id = f.ips_usuario_id) OR
      (u.ips_usuario_id_titular IS NOT NULL AND
       EXISTS (SELECT 1 FROM ips_fatura f WHERE u.ips_usuario_id_titular = f.ips_usuario_id)
      )

For begge disse ønsker du to indekser:ips_fatura(ips_usuario_id) og ips_fatura(ips_usuario_id_titular) . Du kan tjekke forklaringen for at være sikker på, at EXISTS bruger indekset. Hvis ikke, bruger de nyere udgivelser af MySQL indekser for IN :

SELECT COUNT(*)
FROM ips_usuario u  
WHERE u.id IN (SELECT f.ips_usuario_id FROM ips_fatura f) OR
      u.ips_usuario_id_titular IN (SELECT f.ips_usuario_id FROM ips_fatura f);

I begge tilfælde (EXISTS eller IN ) målet er at lave en "semi-join". Altså kun at bøde første række med en kamp frem for alle kampe. Dette er en vigtig effektivitet, fordi det tillader forespørgslen at undgå duplikeringsfjernelse.

Jeg vil spekulere i, at problemet er optimering af or -- normalt resulterer dette i ineffektiv JOIN algoritmer. Men måske er MySQL smart i dit første tilfælde. Men tilføjelsen af ​​IS NULL til det ydre bord smider det af.




  1. Automatiseret test af opgraderingsprocessen til PostgreSQL

  2. Laravel SQLSTATE[22007]:Ugyldigt datetime-format:1292 Forkert datetime-værdi:'2019-03-10 02:00:39' for kolonnen 'updated_at' (sommertid?)

  3. Få værdi baseret på maks. af en anden kolonne grupperet efter en anden kolonne

  4. Java MYSQL Prepared Statement Fejl:Tjek syntaks for at bruge i nærheden af ​​'?' på linje 1