mysql - mysql 5.7查询执行可视化(mysql如何决定查询的执行)
问题描述
我的查询运行缓慢,选择了一些索引而不是其他索引。我试图找到一个工具或指南,使用它我可以弄清楚为什么 MySQL 决定优先考虑 1 个索引或 1 个表(在连接的情况下),以便我可以微调索引或查询。
到目前为止,我还没有遇到过详细解释它的文章或可以为我提供详细信息的工具。
任何输入将不胜感激。提前致谢!
解决方案
随着优化器变得越来越复杂,越来越难以理解它在做什么。最新的改进涉及对可能执行方法的“基于成本”的分析。对于许多查询,很明显一个索引会比另一个更好。
对于正在发生的事情有 4 种观点:
EXPLAIN
是相当有限的。它处理得不是LIMIT
很好,也不一定说哪个步骤使用了文件排序,或者即使有多个文件排序。一般来说,“行”列是有用的,但在某些情况下,它是无用的。简单的规则:大数字是一个坏信号。EXPLAIN EXTENDED
+SHOW WARNINGS;
提供查询的重写版本。这并没有多大作用。它确实提供了区分ON
和WHERE
in的线索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
。较新的优化器为“派生表”(
JOIN ( SELECT ... )
)动态创建索引。但这很少像在返回大量行时重写查询以避免这样的子查询那样有效。(同样,没有人EXPLAINs
会这样指出你。)经常忘记的东西(但确实显示为无法解释的大“行”):
COLLATIONs
必须匹配。使用 PK 集群的技巧:
PRIMARY KEY(foo, id), INDEX(id)
没有任何东西(除了经验)能说明“前缀”索引是多么无用(
INDEX(bar(10))
)。FORCE INDEX
对于实验来说很方便,但对于生产来说几乎总是一个坏主意。在
SELECT
带有 aJOIN
和 a 的WHERE
仅提及其中一个表的情况下,优化器通常会选择其中提到的表WHERE
作为第一个表。然后它将对其他表执行“嵌套循环连接”。
(我应该将其中的一些添加到我的食谱中。“敬请期待”。更新:完成。)
推荐阅读
- c# - C# 中的解耦 MI 提供程序
- android - 不工作 - 使用平板电脑 HUAWEI MediaPad M5 在 Android Studio 上调试模式本机代码 (c/c++)
- java - Java FX 中的“Hello World”应用程序,Java 代码最少
- angular - Angular:Devexpress dxslectbox onselectionchanged 回调函数无法访问此对象
- asp.net - Angular 版本显示不同的版本
- reactjs - 隐藏 Input 组件 React 表带中的自动填充图标
- git - How to switch branch when filename case changes?
- java - 为什么我的 bottomsheetdialog 界面为空
- c++ - 将数组从 C++ 应用程序发送到 webApplication
- reporting-services - 无法访问报表服务上的报表服务器