MySQL 的查询优化器负责决定如何执行 SQL 查询,它会根据多个因素选择最优的执行计划。查询优化器的目标是选择一个成本最低、性能最优的执行计划,以便高效地处理查询。执行计划的选择是基于 MySQL 内部的统计信息和执行策略,下面是查询优化器选择执行计划的关键步骤和考虑因素:

1. 分析查询

查询优化器首先会解析 SQL 查询,生成一个或多个可能的查询执行计划。执行计划包括如何访问表、是否使用索引、如何连接多个表、如何排序数据等。优化器的目标是选择一个执行成本最低的计划。

2. 表连接顺序

  • 当查询涉及多个表时,优化器需要决定表的连接顺序。不同的连接顺序可能会导致不同的执行计划。优化器会尝试多种可能的连接顺序,并选择执行成本最低的一种。
  • 表连接顺序的优化通常是基于表的大小和索引的有效性。优化器倾向于先连接那些过滤数据量较小的表。

3. 索引选择

  • 查询优化器会决定是否使用索引,以及使用哪个索引。MySQL 会检查每个表的索引,并选择能够加速查询的索引。对于索引的选择,优化器通常考虑以下因素:

    • 查询条件是否能利用索引(例如 WHERE 子句中的条件字段)。
    • 是否有覆盖索引(即索引包含了所有查询所需的字段)。
    • 索引的选择性(选择性越高,索引越有效)。
    • 是否能够进行 联合索引(复合索引)。
  • 如果一个查询没有合适的索引,MySQL 可能会选择全表扫描。

4. 连接类型

  • 在涉及多个表的查询中,优化器还需要决定如何连接这些表。常见的连接类型有:

    • Nested Loop Join(嵌套循环连接):通常用于没有索引的情况,通过遍历外部表并查找匹配的行。
    • Hash Join(哈希连接):适用于在内存中构建哈希表的场景,通常用于较大的数据集。
    • Merge Join(合并连接):适用于已排序数据的场景,通过合并排序的结果进行连接。

5. 子查询优化

  • 对于包含子查询的 SQL,优化器会尝试将子查询转换为联接或其他更高效的查询方式。通常,优化器会尽量避免执行不必要的嵌套查询。
  • 如果子查询是 INEXISTS 类型,优化器有时会选择将其转换为 JOIN 查询,从而提高性能。

6. 选择性评估

  • 查询优化器会根据字段的选择性(即不重复值的比例)来评估不同的执行计划。选择性越高的列,索引的效果通常越好,因为它能够有效过滤数据,减少扫描的行数。
  • 优化器会计算每个可能执行计划的成本(通常基于 CPU 时间、I/O 操作和内存使用),并选择成本最低的计划。

7. 统计信息

  • 优化器依赖于表和索引的统计信息来做出决策。统计信息包括每列的数据分布、索引的选择性、表的大小等。优化器通过这些信息来评估不同执行计划的成本。
  • 如果统计信息不准确或过时,可能导致优化器选择不合适的执行计划。因此,定期更新统计信息(使用 ANALYZE TABLE)对查询优化至关重要。

8. 查询重写和简化

  • MySQL 的查询优化器还会尝试重写查询,简化查询语句,或者进行某些优化变换。例如,优化器可能会将 OR 条件转换为多个 UNION 子查询,或将 IN 转换为 EXISTS
  • 对于某些复杂的查询,优化器可能会对查询进行重写,以提高执行效率。

9. 查询缓存

  • 对于查询频繁且结果不常变化的情况,MySQL 会使用查询缓存(如果启用了查询缓存)。如果缓存中存在某个查询的结果,优化器会直接返回缓存结果,而不需要重新执行查询。

10. 成本模型

  • 查询优化器使用成本模型来评估不同执行计划的效率。成本模型会考虑多种因素,包括 I/O 操作的数量、CPU 时间、内存使用、网络传输开销等。
  • 优化器通常会选择执行成本最低的查询计划,但在一些极其复杂的查询中,可能需要调整优化器的参数(如 join_buffer_sizesort_buffer_size 等)来达到更好的执行效果。

11. 查询优化器的执行策略

  • 全表扫描:当没有合适的索引时,优化器可能选择全表扫描。
  • 使用索引:当条件可以利用索引时,优化器会选择使用索引。使用索引可以减少扫描的数据量,提高查询速度。
  • 合并查询:在多个查询条件中,如果某些条件能够合并,优化器会尝试合并它们,减少冗余操作。

12. 示例

例如,查询 SELECT * FROM employees WHERE department = 'HR' AND salary > 50000

  • 优化器会检查 departmentsalary 字段上是否有索引。
  • 如果 department 字段有索引,优化器可能会使用该索引过滤出 HR 部门的记录。
  • 然后,优化器会检查是否使用 salary 字段的索引(如果存在),以便进一步缩小结果集。
  • 如果两个字段都没有索引,优化器可能会选择进行全表扫描,首先扫描所有行以筛选出部门为 HR 的记录,然后进一步筛选出薪资大于 50000 的记录。

总结

MySQL 查询优化器根据多种因素来选择执行计划,包括查询的结构、表连接顺序、索引选择、数据统计信息等。优化器会评估多个候选执行计划的成本,并选择最优的执行计划,以便最小化查询的执行时间和资源消耗。理解查询优化器的工作原理可以帮助开发者编写高效的查询,改善数据库的性能。

MySQL 的查询优化器如何选择执行计划?的更多相关文章

  1. 通过trace分析优化器如何选择执行计划

    1. mysql> show variables like "optimizer_trace%"\G;*************************** 1. row * ...

  2. 通过trace分析优化其如何选择执行计划

    mysql5.6提供了对sql的跟踪trace,通过trace文件能够进一步了解为什么优化其选择执行计划a而不选b执行计划,帮助我们更好的理解优化其的行为. 使用方式:首先打开trace,设置格式为j ...

  3. 高性能可扩展mysql 笔记(六) SQL执行计划及分页查询优化、分区键统计

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 常见业务处理 一.使用数据库处理常见业务: 案例: 如何对评论进行分页展示 使用 EXPLAIN 获得s ...

  4. MySQL——通过EXPLAIN分析SQL的执行计划

    在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序. 下面分别对EXPLAIN命令结果的每一列进行说明: ...

  5. [转]Mysql中的SQL优化与执行计划

    From : http://religiose.iteye.com/blog/1685537 一,如何判断SQL的执行效率? 通过explain 关键字分析效率低的SQL执行计划. 比如: expla ...

  6. Mysql学习---视图/触发器/存储过程/函数/执行计划/sql优化 180101

    视图 视图: 视图是一个虚拟表(非真实存在),动态获取数据,仅仅能做查询操作 本质:[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用.由 ...

  7. [转]使用mysql profiles 来查看sql 语句执行计划

    From : http://blog.csdn.net/radkitty/article/details/4632289 要使用该功能,mysql的版本必须在5.0.37版本以上.否则只能使用expl ...

  8. MySQL执行计划解析

    前言 在实际数据库项目开发中,由于我们不知道实际查询时数据库里发生了什么,也不知道数据库是如何扫描表.如何使用索引的,因此,我们能感知到的就只有SQL语句的执行时间.尤其在数据规模比较大的场景下,如何 ...

  9. 高性能MySql进化论(九):查询优化器常用的优化方式

    1        介绍 1.1     处理流程 当MYSQL 收到一条查询请求时,会首先通过关键字对SQL语句进行解析,生成一颗“解析树”,然后预处理器会校验“解析树”是否合法(主要校验数据列和表明 ...

  10. MySQL 慢查询优化

    为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...

随机推荐

  1. Codeforces Round 961 (Div. 2)

    题目链接:Codeforces Round 961 (Div. 2) 总结:B1wa两发可惜,C出得有点小慢. A. Diagonals fag:贪心 Description:给定一个\(n * n\ ...

  2. ESP32 VScode环境问题

    vsdcode esp-idf插件安装 报错: Espressif\tools\idf-python\3.11.2\python.exe -m pip" is not valid. (ERR ...

  3. pg数据库性能优化(转)

    参数修改的方式 1.修改配置文件 在配置文件data目录下postgresql.conf 中直接修改,修改前记得备份一下原文件.修改完成之后,记得重启数据库哦. 2.命令行的修改方式 ALTER SY ...

  4. Hetao P1184 宝可梦训练家 [ 绿 ][ 背包dp ][ 线性dp ]

    原题 题解 一道超级牛逼的背包变形,想通之后真的很简单,难点在于想到使用 dp 并且用 dp 的值判断是否合法. 首先观察本题的数据范围:\(1\le n,q \le 10^5\) ,可知本题的询问要 ...

  5. mybatis之生命周期及作用域

    SqlSessionFactoryBuilder 一旦创建了SqlSessionFactory之后就没有作用了 局部变量 SqlSessionFactory 可以理解为数据库的连接池 SqlSessi ...

  6. WPF程序性能优化总结

    原文链接: https://blog.csdn.net/u010265681/article/details/77571947 WPF程序性能由很多因素造成,以下是简单地总结: 元素: 1. 减少需要 ...

  7. [ZJOI2019] 语言 题解

    不愧是 \(ZJOI\),<最可做的一道题>都让人一头雾水-- 首先将问题转化到链上. 可以将总共的组数转化为每个点可以到达的城市. 明显给每个点建一棵动态开点线段树,维护可以和他通商的点 ...

  8. 淘宝H5 sign加密算法

    淘宝H5 sign加密算法   淘宝H5 sign加密算法 淘宝对于h5的访问采用了和客户端不同的方式,由于在h5的js代码中保存appsercret具有较高的风险,mtop采用了随机分配令牌的方式, ...

  9. 【攻防世界】ezbypass-cat

    ezbypass-cat 题目来源 攻防世界 NO.GFSJ1183 题目描述 只有一个登录界面,没有注册界面,扫目录也扫不出有用的文件.sql注入也无果,有些难以下手. 题解一 该题解可能是一个非预 ...

  10. Flink学习(十四) Flink 窗口、时间和水位线

    Flink 框架中支持事件时间.摄入时间和处理时间三种.而当我们在流式计算环境中数据从 Source 产生,再到转换和输出,这个过程由于网络和反压的原因会导致消息乱序.因此,需要有一个机制来解决这个问 ...