【MySQL】从执行计划了解MySQL优化策略

news2025/2/5 8:59:24

文章目录

  • 前言
  • 一、什么是执行计划
    • 1.1. 使用EXPLAIN命令
    • 1.2. 使用PROFILING
  • 二、执行计划生成过程
  • 三、执行计划的操作符
    • 3.1. 查询计划操作符
    • 3.2. 连接操作符
    • 3.3. 辅助操作符
  • 四、执行计划的诊断分析
    • 4.1. 使用EXPLAIN命令
    • 4.2. 检查索引
    • 4.3. 分析查询日志
  • 五、如何分析 EXPLAIN 结果?
    • 5.1. 扫描类型
    • 5.2. 关联类型
    • 5.3. 访问类型
    • 5.4. 行数估算
    • 5.5. 性能优化
    • 5.6. 场景分析
  • 六、总结

前言

在MySQL中,执行计划是优化器根据查询语句生成的一种重要的数据结构,它描述了如何通过组合底层操作实现查询的逻辑。当我们编写一条SQL语句时,MySQL会自动对其进行优化,并生成最优的执行计划以实现更快的查询速度。

各位精通MySQL的大佬们,像往常一样,我们经常会遇见一堆SQL查询要处理。作为一个优秀的MySQL的操盘手,不能让这些SQL语句任性地在数据库中胡乱扔,必须要好好管管它们!

但是,面对复杂的SQL语句和复杂的数据库架构,我们如何才能快速和准确地分析查询性能?难道要求神通广大的数据库教父出山帮忙?

不要担心!在MySQL世界中,EXPLAIN命令就像是一个小巧而灵活的工具,能够帮助你轻松解决这些问题。使用它,并结合我们自己的经验和智慧,我们就可以像成功解锁小学奥数一样地优化SQL查询,成为MySQL中的一名优秀演员。

废话不多说,现在就让我们开始吧,让我们去通过熟悉每个查询的执行过程,并用一颗豁达的心态理解每个SQL查询的优化分析!

本文将介绍MySQL执行计划的相关知识。首先我们将介绍执行计划的概念以及MySQL优化器是如何生成执行计划的,然后我们将深入探讨执行计划中各种类型的操作符,最后我们将讨论如何通过执行计划来诊断性能问题。

一、什么是执行计划

执行计划是MySQL优化器为了优化查询而生成的一种数据结构,它记录了数据库系统执行查询时所采取的操作流程,即对查询语句的各部分如何进行处理以最终得到查询结果的过程。执行计划通常被表示为一棵树状结构,节点代表不同的操作符(operator),叶子节点代表访问底层数据的方式,例如表扫描或索引查找等。
在这里插入图片描述

获取MySQL查询执行计划的方法有多种,下面介绍两种常用的方法:

1.1. 使用EXPLAIN命令

EXPLAIN命令可以帮助我们分析查询的执行计划,帮助我们发现潜在的性能问题。我们可以通过以下命令来使用:

EXPLAIN SELECT *
FROM employees
WHERE salary > 50000;

执行以上命令后,MySQL将返回一张表格,其中包含了查询语句所使用的索引、扫描的行数以及各个步骤的 cost 等信息。

1.2. 使用PROFILING

MySQL提供了一个 PROFILING 工具,能够记录 MySQL 服务器上连接和查询的操作时间,包括每个 SQL 语句执行的时间以及资源的消耗。我们可以通过以下命令来启用 PROFILING:

SET profiling = 1;

然后运行我们要分析的查询语句。
最后,我们可以查看查询的 profile 信息,例如:

SHOW PROFILE ALL FOR QUERY n;

其中 n 表示查询语句的 ID,它可以通过如下命令获取:

SHOW PROFILES;

以上就是获取MySQL执行计划的两种常用方法,你需要根据具体情况选择不同的方法来获取和分析执行计划。

二、执行计划生成过程

在查询过程中,MySQL优化器必须决定查询的最佳执行计划。这个过程通常称为查询优化。查询优化的目标是选择最小代价的执行计划,也就是要在所有可能的执行计划中选择一个最快的执行计划。查询优化可以看作是一个搜索空间的问题,其中搜索空间包括所有可能的执行计划。
以下是MySQL优化器确定执行计划的一般流程:

  • 解析SQL语句并构造语法树。MySQL首先解析SQL语句,并使用语法树表示查询。语法树由各种操作符和表达式组成。

    例如,下面是一个查询语句的语法树:

     SELECT *
        FROM employees
        WHERE salary > 50000;
    
    • 生成所有可能的执行计划。接下来,MySQL优化器将生成所有可能的执行计划。它会尝试所有可能的操作顺序和访问方法,以找到最优的执行计划。
    • 估算每个执行计划的代价。对于每个执行计划,MySQL会估算其代价并选择代价最小的执行计划。代价通常由磁盘I/O,内存使用等因素组成。
    • 执行查询。最后,MySQL执行计划并返回结果。

三、执行计划的操作符

MySQL执行计划中的操作符分为三大类:查询计划操作符、连接操作符和辅助操作符。下面我们将分别介绍这三种操作符。

3.1. 查询计划操作符

查询计划操作符包括以下类型:

  • 表扫描(Table scan):这是一种简单的操作,它通过遍历整个表来检索记录。当表没有索引或索引不能用于查询时,MySQL就会采用这种方式。

查询示例:

SELECT *
    FROM employees;
  • 索引查找(Index lookup):当查询条件中包含索引列或者覆盖索引时,MySQL会使用索引查找操作。这个操作通常比表扫描快很多。

查询示例:

SELECT *
FROM employees
WHERE emp_id = 1001;
  • 范围查找(Range lookup):当查询条件中包含范围操作符(如>、<、BETWEEN、IN等)时,MySQL会采用范围查找操作。

查询示例:

SELECT *
FROM employees
WHERE salary BETWEEN 40000 AND 60000;
  • 全文搜索(Fulltext search):当需要在全文中搜索某个关键字时,MySQL会采用全文搜索操作。但是它要求表必须有全文索引。

查询示例:

SELECT *
FROM articles
WHERE MATCH(title, body) AGAINST ('MySQL');
  • 排序(Sort):当查询需要按照指定的排序规则显示结果时,MySQL采用排序操作。

查询示例:

SELECT *
FROM employees
ORDER BY salary DESC;
  • 分组(Group):当需要对结果集分组时,MySQL会采用分组操作符。

查询示例:

SELECT department, AVG(salary)
FROM employees
GROUP BY department;
  • 聚合(Aggregation):当需要对整个表或者某一部分进行聚合操作时,MySQL采用聚合操作符。

查询示例:

SELECT COUNT(*)
FROM employees;

3.2. 连接操作符

连接操作符用于将不同数据源的数据进行连接。MySQL支持以下几种连接操作符:

  • 等值连接(Equal join):当两个表中包含相同的关键字(也就是外键)时,MySQL会使用等值连接操作符实现连接操作。

查询示例:

SELECT *
FROM employees JOIN departments
ON employees.department_id = departments.department_id;
  • 非等值连接(Non-equal join):当连接条件使用非等于运算符时(如>、<、BETWEEN等),MySQL会使用非等值连接操作符。

查询示例:

SELECT *
FROM employees JOIN salaries
ON employees.emp_id = salaries.emp_id AND salaries.salary > 50000;
  • 自连接(Self join):也称为自连接操作,它将一个表与其自身进行连接。

查询示例:

SELECT a.emp_name AS name1, b.emp_name AS name2
FROM employees a, employees b
WHERE a.manager_id = b.emp_id;
  • 外连接(Outer join):当我们需要查询两个表的记录时,无论这两个表是否存在相同的关键字,我们都可以使用外连接操作符进行连接。

查询示例:

SELECT *
FROM employees LEFT JOIN salaries
ON employees.emp_id = salaries.emp_id;

3.3. 辅助操作符

辅助操作符是MySQL执行计划中的其他操作。这些操作通常用于优化性能,包括以下几种类型:

  • 索引合并(Index merge):当查询涉及多个索引时,MySQL会将这些索引进行合并来提高性能。

查询示例:

SELECT *
FROM employees
WHERE emp_id = 1001 AND salary > 50000;
  • 子查询(Subquery):当一个查询需要嵌套在另一个查询之内时,MySQL会使用子查询操作符。

查询示例:

SELECT *
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
  • 临时表(Temporary table):当查询涉及到大量数据或者存在复杂的连接关系时,MySQL会在磁盘上创建一个临时表来处理查询。

查询示例:

SELECT *
FROM employees JOIN salaries JOIN departments
ON employees.emp_id = salaries.emp_id AND employees.department_id = departments.department_id;

以上就是MySQL执行计划中各种操作符的介绍。这些操作符在执行计划生成和性能优化中都会扮演重要的角色。

四、执行计划的诊断分析

当我们发现MySQL的性能有问题时,我们可以通过执行计划来诊断性能问题。下面是一些常用的技巧:

4.1. 使用EXPLAIN命令

EXPLAIN命令可以帮助我们分析查询的执行计划,帮助我们发现潜在的性能问题。我们可以通过以下命令来使用:

EXPLAIN SELECT *
FROM employees
WHERE salary > 50000;

输出结果将告诉我们MySQL所采取的操作顺序和访问方式以及每个操作的代价。

4.2. 检查索引

在许多情况下,我们可以通过添加适当的索引来提高查询性能。我们可以使用以下命令检查表上的索引:

SHOW INDEXES FROM employees;

输出结果将告诉我们索引的名称,类型,所包含的列等信息。

4.3. 分析查询日志

我们可以通过查看MySQL的查询日志来分析查询的执行情况。我们可以使用以下命令启用查询日志:
ini复制代码SET GLOBAL general_log = ‘ON’;

然后,我们可以查看查询日志文件,例如:

ail -f /var/log/mysql/general.log

以上就是使用执行计划诊断MySQL性能问题的基本技巧。在实际工作中,我们可以根据具体情况采用不同的方法来分析执行计划并优化查询性能。

五、如何分析 EXPLAIN 结果?

在使用EXPLAIN命令获取MySQL查询执行计划后,我们需要对结果进行分析,以便识别潜在的性能问题。以下是一些常用的分析方法:

5.1. 扫描类型

扫描类型(Scan Type)是显示在查询计划耗时列中的一项指标。通过这个指标,我们可以了解MySQL是否使用了索引或者全表扫描来访问数据。通常情况下,如果出现 ALL、index 和 range 等扫描类型,就意味着性能可能受到影响。其中:

  • ALL 表示全表扫描,即扫描了整个表的数据。
  • index 表示使用了索引扫描,但需要在索引中查找需要的记录。
  • range 表示使用了索引范围查找,即使用了部分索引进行查找。

5.2. 关联类型

关联类型是指在连接操作中使用的算法。如果查询计划中出现了 Equa Join、Ref、Index Merge 等关联类型,说明MySQL在执行查询时能够充分利用索引,这通常能提高查询性能。其中:

  • Equa Join表示MySQL使用等值连接(内连接),处理两张表中相同键值的行。
  • Ref表示MySQL使用非等值连接,处理两张表中不同键值的行。
  • Index Merge表示MySQL使用了索引合并算法,将多个索引合并来加速查询。

5.3. 访问类型

访问类型(Access Type) 是指 MySQL 在执行查询时,如何获取数据的方式。常见的访问类型包括:

  • Index: 表示使用了覆盖索引来访问表中的数据,即只需要使用索引就可以获取所需的数据。
  • Index-full scan: 表示使用了全表扫描索引的方式来获取数据,但只访问了索引部分的数据。
  • Full-text: 表示使用了全文搜索来获取数据。

5.4. 行数估算

查询计划中的 rows 列表示执行某个步骤时,MySQL 估算的行数。如果进行查询的表很大或者存在大量的数据,则行数估算可能会存在偏差。这种情况下,我们需要特别关注具体的查询步骤和访问类型,以确定是否存在性能问题。

5.5. 性能优化

根据查询执行计划,我们可以判断是否有性能瓶颈,需要对 SQL 查询语句进行优化。优化建议取决于具体的查询计划,例如:

  • 在查询计划中使用了索引,请确保使用正确的索引并创建合适的索引来支持查询。
  • 如果查询计划使用了全表扫描,请尝试减少查询的数据量以避免全表扫描。
  • 如果查询计划中出现了文件排序或临时表操作,请考虑通过更改查询语句或优化表结构来避免这些操作。

5.6. 场景分析

给大家举一个具体的示例来详细说明如何分析 EXPLAIN 结果。
假设我们有以下查询语句:

EXPLAIN SELECT *
FROM orders o JOIN customers c ON o.customer_id = c.customer_id
WHERE o.order_date >= '2022-01-01' AND c.address LIKE '%Beijing%';

得到的查询计划结果如下:

+----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref                         | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+
|  1 | SIMPLE      | c     | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL                        | 1000 |   100.00 | Using where    |
|  1 | SIMPLE      | o     | NULL       | ref  | customer_id   | customer_id | 4       | worldsql.c.customer_id |    2 |    11.11 | Using index    |
+----+-------------+-------+------------+------+---------------+------+---------+-----------------------------+------+----------+----------------+

我们将根据这个查询计划结果可以进行如下分析:
(1)扫描类型
在这个查询计划中,第一行表示 customers 表的扫描类型是 ALL,即执行了全表扫描。这通常会降低MySQL查询性能,因此我们应该检查是否在表上创建了适当的索引来优化查询。
(2)关联类型
关联类型是 SIMPLE,表示这是一个简单的非子查询。同时,我们还可以看到这里使用了 Equa Join 算法,即使用内连接处理两张表中相同键值的行。这通常是MySQL执行联接操作时的最佳算法之一。
(3)访问类型
在这个查询计划中,我们还可以看到,orders 表使用了 ref 访问类型,即使用了索引扫描来获取所需数据。这通常比全表扫描更加高效,因此这是一个好的访问类型。
(4) 行数估算
在这个查询计划中,rows 行数估算列显示为 1000,而实际上 customers 表中只有 1000 行。这意味着MySQL执行了全表扫描并扫描了整个表的所有行。这通常会影响查询性能,因此我们应该检查表上是否存在适当的索引。
(5)性能优化
针对以上分析结果,我们可以考虑以下优化策略:

  • 创建索引:为 customers 表上的 address 列创建索引,以避免全表扫描。
  • 设计合适的索引:为 orders 表上的 order_date 和 customer_id 列创建复合索引来支持查询,可以进一步提高查询性能。

实际sql查询执行,借助通过分析 EXPLAIN 的结果,我们可以确定如何针对性地优化查询语句以提高性能。

六、总结

EXPLAIN 命令就像是一个卧虎藏龙的武林秘籍,使用它能够让MySQL查询变得轻松愉快。在这里,我们可以看到每个查询都是一场表演,有着自己的角色和特点。

扫描类型就像是一个吃货,它会吃遍整个表才能满足胃口;而关联类型就像是一个心机婊,它总是喜欢暗示你要去找另外的表玩耍。而访问类型则是一个聪明的程序员,它总是想方设法通过索引快速获取所需数据。

然而,行数估算却像是一个嘴巴不太靠谱的推销员,它总是高估自己的能力,并且喜欢随意地浪费时间和精力。

幸运的是,在这个MySQL世界中,你永远不会孤单。通过使用 EXPLAIN 命令并对查询计划结果进行分析,我们可以更好地理解MySQL执行查询的过程,找到性能瓶颈,并采取相应的优化措施。

最后,要记住:优化MySQL查询不仅需要技能,还需要耐心和毅力。但是,当你看到查询计划明显优化后,你会感觉整个人都充满了力量和信心!

言归正传,MySQL是一个功能强大的数据库系统,它可以应用于许多不同的场景。为了发挥其最大的性能潜力,我们需要深入了解MySQL的执行计划和查询优化技术,并使用这些知识来诊断和优化查询性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761621.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch 欠拟合和过拟合 多项式回归

欠拟合 训练误差和验证误差都有&#xff0c;还可能比较严重&#xff0c; 但它们之间仅有差距不大。 这个时候模型不能降低训练的误差&#xff0c;有可能是我们设计的模型简单了&#xff0c;表达能力不足&#xff0c; 捕获试图学习的模式比较难。由于我们的训练和验证误差之间的…

java——this、封装、static修饰成员变量、成员方法

目录 ☂️this的用法 1.访问当前对象的成员变量 2.访问当前对象的成员方法 3.调用当前对象的其他构造方法来简化代码 ☂️封装 什么是封装&#xff1f; 访问修饰限定符 ☂️static修饰成员变量 ☂️static修饰成员方法 ☂️this的用法 1.访问当前对象的成员变量 我们…

容器运行时

容器运行时 Docker运行时Containerd运行时CRI 版本支持Containerd安装配置 systemd cgroup 驱动 CRI-O运行时Mirantis 容器运行时 目前k8s支持的几个常用的运行时 containerdCRI-ODocker EngineMirantis Container Runtime v1.24 之前的 Kubernetes 版本直接集成了 Docker Engi…

IDEA+spring boot+activiti+shiro+layui+Mysql权限管理系统源码

IDEAspring bootactivitishirolayuiMysql权限管理系统 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.主页3.用户管理4.部门管理5. 菜单管理6. 角色管理7. 字典管理8.定时任务9.操作日志10.生成管理 三、部分代码UserMapper.javaUserController.javaUser.java 四、其他获…

Python Flask构建微信小程序订餐系统 (七)

🔥 账号管理显示状态 🔥 账号管理选择状态后并显示 修改前 修改后 运行效果 🔥 账号管理执行账号的删除 🔥 修改前 修改后 这里使用的图标库 font awesome</

引入Vue的方式

1.cdn引入 <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

竞赛管理系统实现自动化测试

目录 一、为竞赛管理系统设计测试用例 二、根据测试用例进行测试 登录页面测试 功能测试 界面测试 用户注册页面 功能测试 界面测试 竞赛信息列表页面测试 界面测试 添加竞赛信息页面测试 功能测试 界面测试 修改竞赛信息页面测试 功能测试 一、为竞赛管理…

Rollup 的作用、使用教程、支持 Vue、以及与 Webpack / Babel 的区别

一、前置知识 没接触过前端模块化概念的同学可先参考&#xff1a;JS & Node 模块化解释&#xff1a;AMD、UMD、CommonJS、 ESM 二、什么是 Rollup &#xff1f; Rollup 工具可以将代码转成不同模块&#xff0c;实现一套代码多端&#xff08;浏览器/Node&#xff09;引入…

SpringBoot的静态资源文件访问问题

一、采用默认的文件存放位置&#xff1a; Spring Boot 对静态资源映射提供了默认配置&#xff0c; 默认将 /** 所有访问映射到以下目录&#xff1a; classpath:/static classpath:/public classpath:/resources classpath:/META-INF/resources在如上路径的文件可以被直接访问…

Havoc!新的开源命令和控制C2框架

工具介绍 Havoc是一款现代化可扩展的后渗透命令控制框架&#xff0c;可作为Cobalt Strike和Brute Ratel等付费选项的替代方案。 关注【Hack分享吧】公众号&#xff0c;回复关键字【230618】获取下载链接 Havoc包含各种各样的模块&#xff0c;允许渗透测试人员&#xff08;和黑…

Rust 数据类型 之 结构体(Struct)

目录 结构体&#xff08;Struct&#xff09; 定义与声明 结构体定义 结构体实例 结构体分类 单元结构体&#xff08;Unit Struct&#xff09; 元组结构体&#xff08;Tuple Struct&#xff09; 具名结构体&#xff08;Named Struct&#xff09; 结构体嵌套 结构体方法…

华为云ROMA Connect 的智能集成 – 现代企业数字化转型的新利器

在当今数字信息智能化的时代&#xff0c;人工智能技术逐渐深入企业的生产流程和实践中。人工智能的应用成为现代企业数字化转型的新利器。华为云的ROMA Connect作为企业级的融合集成服务 EiPaaS平台&#xff0c;从今年开始也进入了人工智能技术&#xff0c;针对几个主要的企业集…

新一代iPaaS全域融合集成平台ROMA Connect HDC.Cloud 2023内容值得再读!

华为云下一代ROMA Connect HDC.Cloud 2023 精彩内容摘要&#xff1a; 7月9号 分论坛上嘉宾分享一站式融合集成平台解决的用户痛点、应用场景、新一代全域升级的新特性、以及伙伴分享案例干活 ROMA Connect 展台提供开发者体验全新升级版ROMA Connect的 AI智能集成 HDC.Cloud…

华为OD机试真题 Java 实现【战场索敌】【2023 B卷 100分】,深度优先搜索dfs算法,这眼花缭乱的,你这是“战场索鬼”吧?

目录 专栏导读一、题目描述二、输入描述三、输出描述四、深度优先搜索dfs五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明4、如果增加目标敌人数量K为55、来&#xff0c;上强度 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于…

从零开始 Spring Cloud 4:Nacos

从零开始 Spring Cloud 4&#xff1a;Nacos 图源&#xff1a;laiketui.com Nacos 是 Alibaba 研发的用于 Spring Cloud Alibaba 的服务注册中心组件&#xff0c;符合 Spring Cloud 官方标准&#xff0c;同样被 Spring Cloud 官方接纳&#xff0c;所以我们可以在 Spring Cloud …

FPGA XDMA 中断模式实现 PCIE3.0 测速试验 提供工程源码和QT上位机源码

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案XDMA简介XDMA中断模式QT上位机及其源码 5、vivado工程详解6、上板调试验证7、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xf…

同步和异步的区别

同步&#xff0c;可以理解为在执行完一个函数或方法之后&#xff0c;一直等待系统返回值或消息&#xff0c;这时程序是处于阻塞的&#xff0c;只有接收到返回的值或消息后才往下执行其他的命令&#xff1b; 异步&#xff0c;执行完函数或方法后&#xff0c;不必阻塞性地等待返回…

缓存服务使用总结

1、介绍 分布式缓存方案缓存服务搭建 2、分布式缓存方案&#xff08;重点掌握&#xff09; 2.1、什么是缓存 通常将数据从数据库中同步一份到内存中&#xff0c;客户端直接从内存中查询数据&#xff0c;减少了和数据库的交互次数&#xff0c;提高查询性能&#xff08;因为内…

什么是 WebSocket?Java 中如何实现 WebSocket?

什么是 WebSocket&#xff1f;Java 中如何实现 WebSocket&#xff1f; WebSocket 简介 WebSocket 是一种新型的网络协议&#xff0c;它允许客户端和服务器之间进行双向通信&#xff0c;可以实现实时数据交互。WebSocket 协议是基于 HTTP 协议的&#xff0c;使用标准的 TCP 连…

java项目之(超市管理系统ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的超市管理系统。技术交流和部署相关看文章末尾&#xff01; 目录 开发环境&#xff1a; 后端&#xff1a; 前端&#xff1a; 数据库&…