Di Query 3, Anda pada dasarnya menjalankan subquery untuk setiap baris mybigtable melawan dirinya sendiri.
Untuk menghindari ini, Anda perlu membuat dua perubahan besar:
PERUBAHAN UTAMA # 1: Refactor the Query
Ini pertanyaan asli Anda
Select count(*) as total from mybigtable
where account_id=123 and email IN
(select distinct email from mybigtable where account_id=345)
Kamu bisa mencoba
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;
atau mungkin hitungan per email
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;
PERUBAHAN UTAMA # 2: Pengindeksan yang Tepat
Saya pikir Anda sudah memiliki ini sejak Kueri 1 dan Kueri 2 berjalan cepat. Pastikan Anda memiliki indeks gabungan pada (account_id, email). Lakukan SHOW CREATE TABLE mybigtable\G
dan pastikan Anda memilikinya. Jika Anda tidak memilikinya atau jika Anda tidak yakin, tetap buat indeks:
ALTER TABLE mybigtable ADD INDEX account_id_email_ndx (account_id,email);
UPDATE 2012-03-07 13:26 EST
Jika Anda ingin melakukan NOT IN (), ubah INNER JOIN
to a LEFT JOIN
dan periksa sisi kanan NULL, seperti ini:
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
Silakan baca dua tautan ini untuk melakukan GABUNG
Ini adalah Video YouTube yang luar biasa tempat saya belajar untuk memperbaiki pertanyaan dan buku yang menjadi dasarnya