[英]Mysql Explain Query with type “ALL” when an index is used
我在Mysql中运行了一个查询,如下所示:
EXPLAIN
SELECT *
FROM(
SELECT * # Select Number 2
FROM post
WHERE parentid = 13
ORDER BY time, id
LIMIT 1, 10
) post13_childs
JOIN post post13_childs_childs
ON post13_childs_childs.parentid = post13_childs.id
结果是:
id |select_type |table |type |possible_keys |key |key_len |ref |rows |Extra
1 |PRIMARY |<derived2> |ALL | NULL | NULL |NULL |NULL |10 |
1 |PRIMARY |post13_childs_childs|ref |parentid |parentid |9 |post13_childs.id |10 |Using where
2 |DERIVED |post |ALL |parentid |parentid |9 | |153153 |Using where; Using filesort
这意味着它使用了索引parentid
但是由于ALL
和153153
而扫描了所有行。 为什么索引无法帮助Full Scannig
?
虽然如果我单独运行派生查询(选择#2) ,如下所示:
Explain
SELECT * FROM post
WHERE parentid=13
ORDER BY time , id
LIMIT 1,10
结果是理想的:
id |select_type |table |type |possible_keys |key |key_len |ref |rows |Extra
1 |SIMPLE |post |ref |parentid |parentid |9 |const|41 |Using where; Using filesort
表格post
有以下索引:
总行数 - > 141280。
13
岁儿童的数量( parentid=13
) - > 41
儿童11523
- > 10119
当我添加(parent,time,id)
索引(parent,time,id)
第一个查询的问题将通过13
- > 40行的explin输出来解决,输入:ref
对于11523
- > 19538行,请输入:ref !!! 这意味着检查所有11423
行的子行,而我限制前10行。
你的子查询:
SELECT * # Select Number 2
FROM post
WHERE parentid = 13
ORDER BY time, id
LIMIT 1, 10;
这显然提到了三列,加上所有其他列你有三个索引。 以下是它们的使用方法:
order by
子句中提到,但它是第二个条件 where
子句。 但是,在拉出正确的数据之后,需要明确地对其进行排序。 parentid
的条件。 只是为了介绍为什么优化很难。 如果您有少量数据(比如表格适合一页或两页),那么全表扫描后跟排序可能就好了。 如果大多数parentid
值是13
,那么第二个索引可能是最坏的情况。 如果表不适合内存,那么第三个将非常慢(称为页面颠簸 )。
此子查询的正确索引是满足where
子句并允许排序的索引。 该指数是parentid, time, id
。 这不是覆盖索引(除非这些是表中的所有列)。 但是由于limit
子句,它应该将实际行的命中数减少到10。
请注意,对于完整查询,您需要parentid
上的索引。 并且,幸运的是,关于parentid, time, id
的索引算作这样的索引。 因此,您可以删除该索引。 time, id
索引可能不是必需的,除非您需要其他查询。
您的查询也只过滤那些自己有“孩子”的“孩子”。 很可能不会返回任何行。 你真的想要一个left outer join
吗?
作为最后的评论。 我假设此查询是您的真实查询的简化。 查询从两个表中提取所有列 - 这两个表是相同的。 也就是说,您将从相同的表中获取重复的列名。 您应该有列别名以更好地定义列。
执行任何索引无法帮助的ORDER BY都可能导致性能下降。 对于内部查询,我将在(parentID,time,id)上设置覆盖索引,以便WHERE和ORDER BY子句都可以使用索引。 由于parentID也是连接后缀的基础,所以去那里并且非常快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.