sql >> Databasteknik >  >> RDS >> Mysql

Varför är den här mysql-frågan (med noll-kontroll) så långsammare än den här andra?

Jag är förvånad över att båda är snabba. Jag skulle föreslå att du ersätter 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);

Och för det andra:

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)
      )

För båda dessa vill du ha två index:ips_fatura(ips_usuario_id) och ips_fatura(ips_usuario_id_titular) . Du kan kontrollera förklara för att vara säker på att EXISTS använder indexet. Om inte, använder de nyare versionerna av MySQL index för 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 båda fallen (EXISTS eller IN ) målet är att göra en "semi-join". Det vill säga att bara böta första raden med en match snarare än alla matcher. Detta är en viktig effektivitet, eftersom det tillåter frågan att undvika dubbelarbete borttagning.

Jag skulle spekulera i att problemet är optimeringen av or -- vanligtvis resulterar detta i ineffektiva JOIN algoritmer. Men kanske MySQL är smart i ditt första fall. Men tillägget av IS NULL till det yttre bordet kastar det av sig.




  1. MySQL bulk INFOGA eller UPPDATERA

  2. Byt från SQLite till PostgreSQL i ett nytt Rails-projekt

  3. Hur kan jag välja från värdelistan i SQL Server

  4. Hur man genererar skript för att aktivera alla främmande nyckelbegränsningar i SQL Server Database - SQL Server / TSQL Tutorial Del 78