Het verbaast me dat beide snel zijn. Ik zou willen voorstellen om ze te vervangen door 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);
En voor de tweede:
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)
)
Voor beide wilt u twee indexen:ips_fatura(ips_usuario_id)
en ips_fatura(ips_usuario_id_titular)
. U kunt de uitleg controleren om er zeker van te zijn dat EXISTS
maakt gebruik van de index. Zo niet, dan gebruiken de nieuwere releases van MySQL indexen voor 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);
In beide gevallen (EXISTS
of IN
) het doel is om een "semi-join" te doen. Dat wil zeggen, om alleen de eerste rij te boeten met een wedstrijd in plaats van alle wedstrijden. Dit is een belangrijke efficiëntie, omdat het de query in staat stelt om het verwijderen van dubbele kopieën te voorkomen.
Ik zou speculeren dat het probleem de optimalisatie is van de or
-- meestal resulteert dit in inefficiënte JOIN
algoritmen. Misschien is MySQL in uw eerste geval echter slim. Maar de toevoeging van de IS NULL
naar de buitenste tafel gooit het weg.