In Abfrage 3 führen Sie grundsätzlich eine Unterabfrage für jede Zeile von mybigtable gegen sich selbst aus.
Um dies zu vermeiden, müssen Sie zwei wichtige Änderungen vornehmen:
WICHTIGE ÄNDERUNG 1: Refaktorieren Sie die Abfrage
Hier ist Ihre ursprüngliche Anfrage
Select count(*) as total from mybigtable
where account_id=123 and email IN
(select distinct email from mybigtable where account_id=345)
Du könntest es versuchen
select count(*) EmailCount from
(
select tbl123.email from
(select email from mybigtable where account_id=123) tbl123
INNER JOIN
(select distinct email from mybigtable where account_id=345) tbl345
using (email)
) A;
oder vielleicht die Anzahl pro E-Mail
select email,count(*) EmailCount from
(
select tbl123.email from
(select email from mybigtable where account_id=123) tbl123
INNER JOIN
(select distinct email from mybigtable where account_id=345) tbl345
using (email)
) A group by email;
WICHTIGE ÄNDERUNG 2: Richtige Indizierung
Ich denke, Sie haben dies bereits, da Abfrage 1 und Abfrage 2 schnell ausgeführt werden. Stellen Sie sicher, dass Sie einen zusammengesetzten Index für (account_id, email) haben. Tun Sie SHOW CREATE TABLE mybigtable\G
und stellen Sie sicher, dass Sie eine haben. Wenn Sie es nicht haben oder nicht sicher sind, erstellen Sie den Index trotzdem:
ALTER TABLE mybigtable ADD INDEX account_id_email_ndx (account_id,email);
UPDATE 2012-03-07 13:26 EST
Wenn Sie ein NOT IN () ausführen möchten, ändern Sie das INNER JOIN
in a LEFT JOIN
und überprüfen Sie, ob die rechte Seite NULL ist, wie folgt:
select count(*) EmailCount from
(
select tbl123.email from
(select email from mybigtable where account_id=123) tbl123
LEFT JOIN
(select distinct email from mybigtable where account_id=345) tbl345
using (email)
WHERE tbl345.email IS NULL
) A;
UPDATE 2012-03-07 14:13 EST
Bitte lesen Sie diese beiden Links, um JOINs zu machen
Hier ist ein großartiges YouTube-Video, in dem ich gelernt habe, Abfragen und das Buch, auf dem es basiert, umzugestalten