En la consulta 3, básicamente está ejecutando una subconsulta para cada fila de mybigtable contra sí misma.
Para evitar esto, debe hacer dos cambios importantes:
CAMBIO PRINCIPAL # 1: Refactorizar la consulta
Aquí está tu consulta original
Select count(*) as total from mybigtable
where account_id=123 and email IN
(select distinct email from mybigtable where account_id=345)
Tu podrías intentar
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;
o tal vez el recuento por correo electrónico
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;
CAMBIO PRINCIPAL # 2: indexación adecuada
Creo que ya tiene esto ya que la Consulta 1 y la Consulta 2 se ejecutan rápidamente. Asegúrese de tener un índice compuesto en (account_id, email). Haz SHOW CREATE TABLE mybigtable\G
y asegúrate de tener uno. Si no lo tiene o si no está seguro, cree el índice de todos modos:
ALTER TABLE mybigtable ADD INDEX account_id_email_ndx (account_id,email);
ACTUALIZACIÓN 2012-03-07 13:26 EST
Si desea hacer un NOT IN (), cambie el INNER JOIN
a ay LEFT JOIN
verifique que el lado derecho sea NULL, de esta manera:
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;
ACTUALIZACIÓN 2012-03-07 14:13 EST
Lea estos dos enlaces sobre cómo hacer JOIN
Aquí hay un gran video de YouTube donde aprendí a refactorizar consultas y el libro en el que se basó