我的查询运行缓慢,并且某些索引被选中。我试图找到一种工具或指南,通过它我可以弄清楚为什么MySQL决定优先于1个索引或1个表(在连接的情况下),以便我可以微调索引或查询。 / p>
到现在为止,我还没有看到详细解释它的文章或能为我提供详细信息的工具。
任何输入将不胜感激。在此先感谢一吨!
答案 0 :(得分:6)
随着优化器变得越来越复杂,它变得越来越难以理解它在做什么。最新的改进包括对可能的执行方法进行“基于成本”的分析。对于许多查询而言,很明显一个索引会比另一个更好。
对发生的事情有4种看法:
EXPLAIN
非常有限。它不能很好地处理LIMIT
,也不一定要说明哪个步骤使用了文件排序,甚至没有多个文件排序。通常,“行”列很有用,但在某些情况下,它是无用的。简单的规则:数字很大是个坏兆头。
EXPLAIN EXTENDED
+ SHOW WARNINGS;
提供了查询的重写版本。这并没有太大作用。它确实提供了ON
中WHERE
和JOINs
之间区别的线索。
EXPLAIN FORMAT=JSON
为基于成本的分析提供了更多细节,并阐明了包括文件排序在内的各个步骤。
“优化程序跟踪”更进一步。 (阅读起来很繁琐。)
至于“可视化”,没有。无论如何,EXPLAIN
和它的朋友只能使用他们拥有的东西。那就是他们没有给出“如果添加INDEX(a,b)会怎样”的线索。那才是真正需要的。它也没有有效地指出您不应“在函数调用中隐藏索引列”。示例:WHERE DATE(dt) = '2019-01-23'
。请注意,某些“运算符”实际上是函数调用。
我已经看到了一些“图形解释”,但它们似乎无非是将EXPLAIN
的行装箱并在它们之间画线。
多年来,我一直在努力解决这些问题,并写了部分答案-即“食谱”。它从另一个方向进行索引编制-解释为给定的SELECT
添加什么索引。不幸的是,它仅适用于更简单的查询。 http://mysql.rjweb.org/doc.php/index_cookbook_mysql
我在这个论坛上处理许多性能问题,希望对下一个要添加的内容有更多的了解。目前,您可以通过发布棘手的查询以及EXPLAIN SELECT
和SHOW CREATE TABLE(s)
来帮助我。
一些随机评论:
“索引合并交集”可能总是 不如复合索引。
“索引合并联合”几乎从未使用过。您也许可以有效地将OR
变成UNION
。
较新的Optimizer为“派生表”(JOIN ( SELECT ... )
)动态创建索引。但是,这很少像重写查询那样有效,因为它避免返回大量行时避免这种子查询。 (同样,EXPLAINs
都不会这样指向您。)
经常遗忘的东西(但确实显示为无法解释的大“行”):COLLATIONs
必须匹配。
利用PK聚类的技巧:PRIMARY KEY(foo, id), INDEX(id)
(经验除外),什么都没有说(INDEX(bar(10))
)几乎没有用的“前缀”索引。
FORCE INDEX
对于实验很方便,但对于生产几乎总是一个坏主意。
在具有SELECT
和JOIN
且仅提及其中一个表的WHERE
中,优化器通常会 选择该表WHERE
中提到的第一个表格。然后它将对其他表进行“嵌套循环连接”。
(我应该在我的食谱中添加一些内容。请保持关注。更新:完成。)