哪个查询更好

时间:2010-11-10 00:54:20

标签: mysql query-optimization

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

我不太确定的第一个查询,它使用的是一个看起来更糟糕的临时表。但我也看到它使用的行数比第二个查询少....

2 个答案:

答案 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上创建一个索引,以摆脱filesorttemporary

答案 1 :(得分:0)

我会说第一个更好。临时表可能不是一个好主意,但子查询不是更好。并且您将为MySQL提供更多选项,以使用内部联接优化查询计划,而不是使用子查询。

只要只返回几行,子查询解决方案就会很快。

但是......第一个和第二个查询似乎不一样,应该是这样吗?