【实战篇】执行计划解析

devtools/2025/3/15 6:35:44/

执行计划解析

获取执行计划

数据库优化器可能会根据连接方式、连接条件等因素选择不同的执行计划。你可以通过 EXPLAIN 关键字查看两个查询的执行计划,以便更好地理解优化器的选择。

EXPLAIN SELECT ...
-- 替换 ... 部分为你的查询内容

观察执行计划并查看其中的关键信息,这可以帮助你理解查询优化器是如何选择执行计划的,从而找到可能导致性能差异的原因。

内容含义

执行计划是数据库优化器生成的一种表示查询执行方式的输出。它提供了关于查询如何执行的详细信息,包括表的访问顺序、使用的索引、连接方式等。

执行计划的输出可能会因数据库管理系统而异,下面是一些通用的解释:

  1. ID: 序号,每个操作的唯一标识符,通常从 1 开始递增。

  2. Select Type: 表示查询的类型,包括 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。

  3. Table: 表名,操作涉及的表。

  4. Type: 访问表的方式,包括 ALL(全表扫描)、INDEX(索引扫描)、range(范围扫描)等。

  5. Possible Keys: 可能用于执行查询的索引。

  6. Key: 实际用于执行查询的索引。

  7. Key Length: 索引的长度。

  8. Ref: 显示连接的列。

  9. Rows: 预计需要检查的行数。

  10. filtered: 表示经过表扫描或索引扫描后,通过过滤条件的行的百分比。具体来说,它表示在执行计划的某个步骤中,有多少行满足查询的 WHERE 子句或其他过滤条件。filtered 列的值范围是 0 到 100,表示过滤条件满足的行的百分比。以下是一些可能的情况:

    • 如果 filtered 为 100%,表示所有经过扫描的行都满足过滤条件。
    • 如果 filtered 为 0%,表示没有一行满足过滤条件。
    • 如果 filtered 介于 0% 和 100% 之间,表示部分行满足过滤条件。

    这个值的大小可以帮助开发人员分析查询性能。如果 filtered 较低,可能意味着过滤条件不够严格,导致了更多的行需要被检查。反之,如果 filtered 较高,则说明过滤条件较为有效,减少了不必要的行扫描,提高了查询性能。

  11. Extra: 其他信息,可能包括文件排序、临时表等。

通过观察执行计划的输出,你可以了解查询是如何执行的,哪些步骤可能导致性能问题。

以下是一些常见的优化提示:

  • 使用索引: 确保查询中的条件列上有索引。
  • 避免全表扫描: 尽量避免 ALL 类型的访问,特别是对大表的情况。
  • 合理使用连接: 确保连接条件足够明确,选择合适的连接类型。
  • 考虑分区表: 对于大表,使用分区表可以提高查询性能。
  • 注意临时表和文件排序: 如果看到 Using temporaryUsing filesort,可能需要考虑索引或调整查询。

访问表的方式

以下是几种常见的访问表的方式:

  1. ALL:

    • 全表扫描,效率最低。所有行都被读取来找到匹配的行。
    • 通常出现是因为缺少合适的索引。
  2. index:

    • 全索引扫描,类似于全表扫描,但扫描的是索引树而不是数据行。
    • 比全表扫描更快,因为索引树的大小通常比数据行小。
  3. range:

    • 范围扫描,通过索引查找位于指定范围内的行。
    • 适用于范围条件查询,比如 BETWEEN, <, >, <=, >= 等。
  4. ref:

    • 非唯一索引扫描,返回所有匹配某一单个值的行。
    • 常见于非唯一索引和前缀索引的查询。
  5. eq_ref:

    • 唯一索引扫描,返回最多一条匹配的行。

    • 通常用于主键或唯一索引查询。

    • 在执行计划中,eq_ref 是一种连接方式,表示等值连接。具体来说,eq_ref 是指使用索引查找关联表的唯一行。

      image

      一般情况下,eq_ref 出现在连接条件中使用了【唯一或主键索引】,并且查询优化器能够确定被引用的表中的每个值只与另一表中的一个唯一值匹配。

      举例说明,假设有两张表 A 和 B,它们通过 A 表的主键或唯一键与 B 表关联。执行计划中的 eq_ref 表示对于 A 表的每一行,在 B 表中都只有一行与之匹配。

      -- 示例表结构
      CREATE TABLE A (id INT PRIMARY KEY,data VARCHAR(255)
      );CREATE TABLE B (id INT PRIMARY KEY,a_id INT,other_data VARCHAR(255),FOREIGN KEY (a_id) REFERENCES A(id)
      );-- 查询
      EXPLAIN SELECT *
      FROM A
      JOIN B ON A.id = B.a_id;
      

      在上述查询中,如果使用了 A 表的主键或唯一键索引,那么连接操作的类型可能会显示为 eq_ref

      总的来说,eq_ref 是一种高效的连接方式,因为它表示连接的列是唯一的,每行都只匹配一次。这通常是通过主键或唯一键来实现的。

  6. const:

    • 常量查询,当查询结果最多有一条匹配的行,并且优化器能够将其视为常量。
    • 通常用于主键或唯一索引的等值查询。
  7. system:

    • 表只有一行(系统表),是 const 类型的特例。
    • 查询效率最高。
  8. NULL:

    • MySQL 无需访问表或索引直接就能得出结果。
    • 例如 SELECT 1 + 1

覆盖索引(Covering Index)

覆盖索引是指一个索引包含了查询所需的所有列,不需要再回表(访问数据行)来获取数据。这样能显著提高查询性能,因为索引通常比数据行小且紧凑。

示例:

假设有一张表 users,有索引 idx_name_email (name, email)

CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(255),email VARCHAR(255),age INT,INDEX idx_name_email (name, email)
);

如果执行以下查询:

SELECT name, email FROM users WHERE name = 'John';

MySQL 可以直接从 idx_name_email 索引中获取 nameemail,而不需要回表查询,从而提高查询性能。

索引下推(Index Condition Pushdown, ICP)

索引下推是在 MySQL 5.6 及之后引入的优化技术。在使用索引扫描时,MySQL 优化器会将查询条件 “推” 到索引扫描过程中,而不是在索引扫描后再进行过滤。

示例:

假设有一张表 employees,有索引 idx_last_name_first_name (last_name, first_name)

CREATE TABLE employees (id INT PRIMARY KEY,last_name VARCHAR(255),first_name VARCHAR(255),hire_date DATE,INDEX idx_last_name_first_name (last_name, first_name)
);

如果执行以下查询:

SELECT * FROM employees WHERE last_name = 'Smith' AND first_name LIKE 'J%';

使用索引下推,MySQL 优化器会在扫描 idx_last_name_first_name 索引时,同时应用 first_name LIKE 'J%' 过滤条件,而不是扫描完索引后再应用过滤条件。这减少了不必要的行访问,提高了查询效率。


http://www.ppmy.cn/devtools/167224.html

相关文章

MySQL与Redis的缓存一致性问题

MySQL与Redis的缓存一致性问题 前言 在学习中&#xff0c;为了提高数据的读取效率&#xff0c;我们往往会使用Redis来作为MySQL数据的缓存&#xff0c;那么&#xff0c;自然就产生了二者间数据的一致性问题。 想要对MySQL和Redis进行数据处理&#xff0c;自然会产生以下问题…

3.14学习总结

今天完成了几道关于二叉树的算法题 关于二叉树的最小最大深度和数据流中的第k大元素&#xff0c;用到优先队列&#xff0c;学习了有关java的基础知识&#xff0c;学习了双指针法。

Windows11使用CMD命令行从零开始创建一个Flask项目并使用虚拟环境

在 Windows 11 中&#xff0c;你可以使用 CMD 命令 创建一个 Flask 项目&#xff0c;并使用 虚拟环境&#xff08;venv 或 pipenv&#xff09; 进行管理。以下是从零开始的完整步骤&#xff1a; 方法 1&#xff1a;使用 venv 创建虚拟环境 1. 打开 CMD 按 Win R&#xff0c;…

Python 逆向工程:2025 年能破解什么?

有没有想过在复杂的软件上扭转局面&#xff1f;到 2025 年&#xff0c;Python 逆向工程不仅仅是黑客的游戏&#xff0c;它是开发人员、安全专业人员和好奇心强的人解开编译代码背后秘密的强大方法。无论您是在剖析恶意软件、分析 Python 应用程序的工作原理&#xff0c;还是学习…

基于javaweb的SpringBoot杂物商城系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

使用 Excel 实现绩效看板的自动化

引言 在日常工作中&#xff0c;团队的绩效监控和管理是确保项目顺利进行的重要环节。然而&#xff0c;面临着以下问题&#xff1a; ​数据分散&#xff1a;系统中的数据难以汇总&#xff0c;缺乏一个宏观的团队执行情况视图。​看板缺失&#xff1a;系统本身可能无法提供合适…

【算法】 【c++】字符串s1 中删除所有 s2 中出现的字符

【算法】 【c】字符串s1 中删除所有 s2 中出现的字符 eg&#xff1a; s1:“helloworld” s2:“wd” 删除后&#xff1a;s1:“helloorl” 1 双循环匹配并删除–>时间复杂度O(n^2) string 里面的删除函数–>erase std::string::erase 是 C 标准库中用于删除字符串中字符…

​​vue-router编程式导航,params传参拿不到

vue-router在4.14版本就废弃这种传参方式了 原因&#xff1a;​​这种传参本来就不是官方推荐的&#xff0c;比如页面刷新会引起参数丢失​ 官方解释 官方解释翻译后的截图&#xff1a; 解决&#xff08;官方推荐了很多种解决方式&#xff0c;下面列举出快捷高效的修改方式&a…