aho*_*hoo 15 mysql sql indexing query-optimization explain
我在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
Run Code Online (Sandbox Code Playgroud)
结果是:
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
Run Code Online (Sandbox Code Playgroud)
这意味着它使用了索引,parentid但是由于ALL和扫描了所有行153153.为什么指数不能帮助不Full Scannig?
虽然如果我单独运行派生查询(选择#2),如下所示:
Explain
SELECT * FROM post
WHERE parentid=13
ORDER BY time , id
LIMIT 1,10
Run Code Online (Sandbox Code Playgroud)
结果是理想的:
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
Run Code Online (Sandbox Code Playgroud)
该表post包含以下索引:
总行
数- > 141280. 13(parentid=13)
的子女数- > 41 岁儿童数11523- > 10119
当我添加索引时(parent,time,id),第一个查询的问题将通过explin输出解决13- > 40行,输入:ref
和for 11523- > 19538 rows,输入:ref !!! 这意味着11423在我限制前10行的同时检查所有子行.
你的子查询:
SELECT * # Select Number 2
FROM post
WHERE parentid = 13
ORDER BY time, id
LIMIT 1, 10;
Run Code Online (Sandbox Code Playgroud)
这显然提到了三列,加上所有其他列你有三个索引.以下是它们的使用方法:
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也是连接后记的基础,所以应该很好去那里并且速度相当快。
| 归档时间: |
|
| 查看次数: |
11922 次 |
| 最近记录: |