2012-07-15 51 views
1

我不确定这个查询是否使用索引。 我如何看?这个查询使用索引,在MySQL中?

mysql> EXPLAIN SELECT au.* FROM users au WHERE au.id IN(SELECT fa.from_user_id FROM approvals fa INNER JOIN personas pp ON fa.persona_id = pp.id WHERE fa.to_user_id=1 AND pp.is_foundation=1 GROUP BY fa.from_user_id) ORDER BY id DESC LIMIT 0, 9999999999; 
+----+--------------------+-------+--------+-----------------------+------------+---------+--------------------+------+----------------------------------------------+ 
| id | select_type  | table | type | possible_keys   | key  | key_len | ref    | rows | Extra          | 
+----+--------------------+-------+--------+-----------------------+------------+---------+--------------------+------+----------------------------------------------+ 
| 1 | PRIMARY   | au | index | NULL     | PRIMARY | 4  | NULL    | 2272 | Using where         | 
| 2 | DEPENDENT SUBQUERY | fa | ref | to_user_id,persona_id | to_user_id | 4  | const    | 396 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | pp | eq_ref | PRIMARY    | PRIMARY | 4  | kjdb.fa.persona_id | 1 | Using where         | 
+----+--------------------+-------+--------+-----------------------+------------+---------+--------------------+------+----------------------------------------------+ 
3 rows in set (0.00 sec) 

回答

3

输出中的key列指示MySQL正在使用的索引。

所以是的,查询使用索引。

在您正在运行的MySQL版本的MySQL文档中,您可以阅读更多关于EXPLAIN的输出信息。例如,如果您正在运行MySQL 5.1,请阅读http://dev.mysql.com/doc/refman/5.1/en/explain-output.html

+0

为什么要过3秒钟,运行此查询,如果是使用索引? – TIMEX 2012-07-15 06:44:17

0

我会很快。是的,用于连接,但不用于过滤记录。请看额外的领域。它应该是“使用索引”,而它的使用其中确实比较慢。

请考虑修改查询以避免子查询。

+0

我认为'使用索引'意味着它使用索引作为覆盖索引。 '使用where'确实意味着它使用WHERE子句的索引。 – Ami 2012-07-15 08:43:20

0

由@Trott回答。尽管我认为你很有能力并且能够制定并尝试替代查询,但仍然存在一个奇怪的MySQL事实(易于监督):MySQL声称自从很久以来,EXISTS可以比IN SELECT更好地优化,作为所寻找的元素,然后在子查询中。

这将是最简单的形式:

EXPLAIN 
    SELECT au.* 
    FROM users au 
    WHERE EXISTS 
    (SELECT fa.from_user_id FROM approvals fa 
    INNER JOIN personas pp ON fa.persona_id = pp.id 
    WHERE fa.from_user_id = au.id 
     AND fa.to_user_id=1 AND pp.is_foundation=1 
    GROUP BY fa.from_user_id) 
    ORDER BY id DESC 
    LIMIT 0, 9999999999;