我怀疑 LEFT JOIN
是否真的比 NOT IN
更好。我刚刚用以下表结构进行了一些测试(如果我错了,请纠正我):
account (id, ....) [42,884 rows, index by id]
play (account_id, playdate, ...) [61,737 rows, index by account_id]
(1) 使用 LEFT JOIN
进行查询
SELECT * FROM
account LEFT JOIN play ON account.id = play.account_id
WHERE play.account_id IS NULL
(2) 使用 NOT IN
进行查询
SELECT * FROM
account WHERE
account.id NOT IN (SELECT play.account_id FROM play)
使用LIMIT 0,...进行速度测试。
LIMIT 0,-> 100 150 200 250
LEFT 3.213s 4.477s 5.881s 7.472s
NOT EXIST 2.200s 3.261s 4.320s 5.647s
Difference 1.013s 1.216s 1.560s 1.825s
我增加限制时,差异越来越大。
使用 EXPLAIN
(1) 使用 LEFT JOIN
的查询
SELECT_TYPE TABLE TYPE ROWS EXTRA
SIMPLE account ALL 42,884
SIMPLE play ALL 61,737 Using where; not exists
(2) 使用 NOT IN
进行查询
SELECT_TYPE TABLE TYPE ROWS EXTRA
SIMPLE account ALL 42,884 Using where
DEPENDENT SUBQUERY play INDEX 61,737 Using where; Using index
似乎左连接没有使用索引。
逻辑:
(1) 使用 LEFT JOIN 查询
在 account 和 play 之间进行 LEFT JOIN,将产生 42,884 * 61,737 = 2,647,529,508 行。然后检查这些行中的 play.account_id 是否为 NULL。
(2) 使用 NOT IN 查询
二分查找需要 log2(N) 步骤来确定项目是否存在。这意味着需要 42,884 * log2(61,737) = 686,144 步骤。
EXPLAIN
吗?你有什么索引? - Jodrell