クエリ3では、基本的にそれ自体に対してmybigtableのすべての行に対してサブクエリを実行しています。
これを回避するには、2つの大きな変更を行う必要があります。
主な変更#1:クエリをリファクタリングする
これが元のクエリです
Select count(*) as total from mybigtable
where account_id=123 and email IN
(select distinct email from mybigtable where account_id=345)
あなたは試すことができます
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;
またはメールあたりの数
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;
主要な変更#2:適切なインデックス作成
クエリ1とクエリ2は高速に実行されているので、これは既にあると思います。(account_id、email)に複合インデックスがあることを確認してください。やるSHOW CREATE TABLE mybigtable\G
と必ずお持ちします。それがない場合、または不明な場合は、とにかくインデックスを作成します。
ALTER TABLE mybigtable ADD INDEX account_id_email_ndx (account_id,email);
UPDATE 2012-03-07 13:26 EST
NOT IN()を実行する場合は、次のようにINNER JOIN
をa に変更してLEFT JOIN
、右側がNULLであることを確認します。
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
JOINの実行に関するこれら2つのリンクをお読みください
ここに私がクエリをリファクタリングすることを学んだ素晴らしいYouTubeビデオとそれが基づいた本があります