EXPLAIN EXTENDED SELECT id, name
FROM member
INNER JOIN group_assoc ON ( member.id = group_assoc.member_id
AND group_assoc.group_id =2 )
ORDER BY registered DESC
LIMIT 0 , 1
输出:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE group_assoc ref member_id,group_id group_id 4 const 3 100.00 Using temporary; Using filesort
1 SIMPLE member eq_ref PRIMARY PRIMARY 4 source_member.group_assoc.member_id 1 100.00
explain extended SELECT
id, name
FROM member WHERE
id
NOT IN (
SELECT
member_id
FROM group_assoc WHERE group_id = 2
)
ORDER BY registered DESC LIMIT 0,1
输出:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY member ALL NULL NULL NULL NULL 2635 100.00 Using where; Using filesort
2 DEPENDENT SUBQUERY group_assoc index_subquery member_id,group_id member_id 8 func,const 1 100.00 Using index; Using where
我不太确定的第一个查询,它使用的是一个看起来更糟糕的临时表。但我也看到它使用的行数比第二个查询少....
答案 0 :(得分:1)
这些查询返回完全不同的结果集:第一个返回第2组成员,第二个返回不第2组成员的所有人。
如果你的意思是:
SELECT id, name
FROM member
LEFT JOIN
group_assoc
ON member.id = group_assoc.member_id
AND group_assoc.group_id = 2
WHERE group_assoc.member_id IS NULL
ORDER BY
registered DESC
LIMIT 0, 1
,那么计划应该是相同的。
您可能会发现这篇文章很有趣:
在member.registered
上创建一个索引,以摆脱filesort
和temporary
。
答案 1 :(得分:0)
我会说第一个更好。临时表可能不是一个好主意,但子查询不是更好。并且您将为MySQL提供更多选项,以使用内部联接优化查询计划,而不是使用子查询。
只要只返回几行,子查询解决方案就会很快。
但是......第一个和第二个查询似乎不一样,应该是这样吗?