MySQL explain SQL分析工具详解与最佳实践

目录

    • 一、explain工具介绍
    • 二、添加示例表和数据用于后续演示
    • 三、explain中的列
      • 3.1、id列
      • 3.2、select_type列
      • 3.3、table列
      • 3.4、partitions列
      • 3.5、type列
        • NULL
        • system
        • const
        • eq_ref
        • ref
        • range
        • index
        • ALL
      • 3.6、possible_keys列
      • 3.7、key列
      • 3.8、key_len列
      • 3.9、ref列
      • 3.10、rows列
      • 3.11、filtered列
      • 3.12、Extra列
        • Using index
        • Using where
        • Using index condition
        • Using temporary
        • Using filesort
        • Select tables optimized away

一、explain工具介绍

  • 使用explain关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL。

  • 通过explain执行SQL语句还能查看优化器优化之后的SQL,紧随其后通过 SHOW WARNINGS; 命令可以得到优化后的查询语句,从而看出优化器优化了什么

    # 例如
    EXPLAIN
    SELECT * FROM role;
    SHOW WARNINGS;
    

    在这里插入图片描述

二、添加示例表和数据用于后续演示

这里会使用角色加菜单关系三张表来做演示。

DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID',`menu_name` varchar(50) DEFAULT NULL COMMENT '菜单名称',`remark` varchar(255) DEFAULT NULL COMMENT '备注',`del_flag` tinyint(4) NULL DEFAULT 0 COMMENT '删除标识 0:已删除 1:未删除 默认0',`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT = '菜单表';INSERT INTO `menu` VALUES (1, '系统管理', '管理系统用户角色菜单相关', 0, '2023-09-28 10:45:41');
INSERT INTO `menu` VALUES (2, '商品管理', '管理系统商品', 0, '2023-09-28 10:46:04');DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID',`role_name` varchar(50) DEFAULT NULL COMMENT '角色名称',`remark` varchar(255) DEFAULT NULL COMMENT '备注',`del_flag` tinyint(4) NULL DEFAULT 0 COMMENT '删除标识 0:已删除 1:未删除 默认0',`create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE,KEY `idx_roleName` (`role_name`)
) ENGINE = InnoDB COMMENT = '角色表';INSERT INTO `role` VALUES (1, '超级管理员', '最大角色', 0, '2023-09-28 10:43:31');
INSERT INTO `role` VALUES (2, '普通人员', '小卡拉米', 0, '2023-09-28 10:45:14');DROP TABLE IF EXISTS `role_menu`;
CREATE TABLE `role_menu`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色菜单关联ID',`role_id` bigint(20) NOT NULL COMMENT '角色ID',`menu_id` bigint(20) NOT NULL COMMENT '菜单ID',PRIMARY KEY (`id`) USING BTREE,KEY `idx_roleId_menuId` (`role_id`,`menu_id`)
) ENGINE = InnoDB COMMENT = '角色菜单关联表';INSERT INTO `role_menu` VALUES (1, 1, 1);
INSERT INTO `role_menu` VALUES (2, 1, 2);
INSERT INTO `role_menu` VALUES (3, 2, 2);

三、explain中的列

explain中有12个列分别代表不同指标,这里会举例介绍。
在这里插入图片描述

3.1、id列

id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的,id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。

3.2、select_type列

select_type 表示对应行是简单还是复杂的查询。

  • 1、simple:简单查询,查询不包含子查询和union
EXPLAIN SELECT * FROM role  WHERE id = 1;

在这里插入图片描述

  • 2、primary:复杂查询中最外层的 select
  • 3、subquery:包含在 select 中的子查询(不在 from 子句中)
EXPLAIN SELECT t1.id,(SELECT menu_name FROM menu WHERE id=t1.menu_id ) AS menuName FROM role_menu t1

在这里插入图片描述

  • 4、union:在 union 中的第二个和随后的 select
EXPLAIN SELECT * FROM role WHERE id=1 UNION SELECT * FROM role WHERE id=2;

在这里插入图片描述

3.3、table列

这一列表示 explain 的一行正在访问哪个表,如果表设置了别名会显示表的别名。

3.4、partitions列

指分区信息。数据库优化有分库、分表、分区;这里的分区值表的分区信息。

3.5、type列

这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围。
依次从最优到最差分别为:system > const > eq_ref > ref > range > index > ALL
一般来说,得保证查询达到range级别,最好达到ref

NULL

mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问表。

EXPLAIN SELECT MIN(id) FROM role;

在这里插入图片描述

system

system是const的特例,表里只有一条元组匹配时为system,可以看SHOW WARNINGS;的结果。

EXPLAIN SELECT * FROM (SELECT '666' AS num FROM dual) t1;
SHOW WARNINGS;

在这里插入图片描述
在这里插入图片描述

const

mysql能对查询的某部分进行优化并将其转化成一个常量(可以看SHOW WARNINGS;的结果)。用于primary key 或 unique key 的所有列与常数比较时,所以表最多有一个匹配行,读取1次,速度比较快。

EXPLAIN SELECT * FROM role WHERE id=1;
SHOW WARNINGS;

在这里插入图片描述
在这里插入图片描述

eq_ref

primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录。这可能是在const 之外最好的联接类型了,简单的 select 查询不会出现这种 type。

EXPLAIN
SELECT * FROM role t1 INNER JOIN role_menu t2 ON t1.id=t2.id where t1.id;

在这里插入图片描述

ref

相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。

EXPLAIN SELECT * FROM role where role_name = '超级管理员';

在这里插入图片描述

range

范围扫描通常出现在 in(), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行。

EXPLAIN SELECT * FROM role where id < 3;

在这里插入图片描述

index

扫描全索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比ALL快一些。

EXPLAIN SELECT role_name FROM role;

在这里插入图片描述

ALL

即全表扫描,扫描你的聚簇索引的所有叶子节点。通常情况下这需要增加索引来进行优化了。

EXPLAIN SELECT * FROM role WHERE del_flag = 1;

在这里插入图片描述

3.6、possible_keys列

这一列显示查询可能使用哪些索引来查找。

  • explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引
    对此查询帮助不大,选择了全表查询。
  • 如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查 where 子句看是否可以创造一个适当的索引来提
    高查询性能,然后用 explain 查看效果。

3.7、key列

这一列显示mysql实际采用哪个索引来优化对该表的访问。

  • 如果没有使用索引,则该列是 NULL。如果想强制mysql使用或忽视possible_keys列中的索引,在查询中使用 force
    index、ignore index。
    # 强制使用idx_roleName索引
    # 需要注意的就算我们指定了需要使用的索引,但是MySQL优化器觉得全表扫描更加高效或者我们指定的索引查询条件无法使用到,还是可能会忽略我们指定的索引。
    EXPLAIN SELECT * FROM role FORCE INDEX(idx_roleName) WHERE role_name = '超级管理员';
    # 忽略使用idx_roleName索引
    EXPLAIN SELECT * FROM role IGNORE INDEX(idx_roleName) WHERE role_name = '超级管理员';
    

3.8、key_len列

这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

举例来说,role_menu的联合索引 idx_roleId_menuId由 role_id 和 menu_id 两个bigint列组成,并且每个bigint是8字节。通
过结果中的key_len=8可推断出查询使用了第一个列:role_id 列来执行索引查找。

EXPLAIN SELECT * FROM role_menu WHERE role_id = 1;

在这里插入图片描述

  • key_len计算规则如下:
    • 字符串,char(n)和varchar(n),5.0.3以后版本中,n均代表字符数,而不是字节数,如果是utf-8,一个数字或字母占1个字节,一个汉字占3个字节,如果是utf-8mb4一个汉字占4个字节
      • char(n):如果存汉字长度就是 3n 字节
      • varchar(n):如果存汉字则长度是 3n + 2 字节,加的2字节用来存储字符串长度,因为varchar是变长字符串
    • 数值类型
      • tinyint:1字节
      • smallint:2字节
      • int:4字节
      • bigint:8字节
    • 时间类型
      • date:3字节
      • timestamp:4字节
      • datetime:8字节 (5.6.4开始,存储开销从8字节降到了5字节)
    • 如果字段允许为 NULL,需要1字节记录是否为 NULL
    • 索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。

3.9、ref列

这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例:role.id)

3.10、rows列

这一列是MySQL估计要读取并检测的行数,注意这个不是结果集里的行数,这个只是预估值和实际值可能有偏差。

3.11、filtered列

filtered指标表示扫描行数和条件过滤结果集的百分比,比如我们这边查询 role_name = ‘超级管理员’,全表扫描总扫描数据集2条过滤出1条得到比值50%。

EXPLAIN SELECT * FROM role  WHERE  role_name = '超级管理员';

在这里插入图片描述

3.12、Extra列

这一列展示的是额外信息。常见的重要值如下:

Using index

使用覆盖索引,mysql执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值

EXPLAIN SELECT role_name FROM role WHERE role_name = '超级管理员';

在这里插入图片描述

Using where

使用 where 语句来处理结果,并且查询的列未全部被索引覆盖

EXPLAIN SELECT * FROM role WHERE role_name = "超级管理员" AND remark = "最大角色";

在这里插入图片描述

Using index condition

尝试只使用索引来获取数据,即能用索引就用;

EXPLAIN SELECT * FROM role WHERE role_name > '超级管理员';

在这里插入图片描述

Using temporary

用临时表存储中间结果,常用于DISTINCT、GROUP BY、ORDER BY 等操作。

EXPLAIN SELECT DISTINCT remark FROM role;

在这里插入图片描述

Using filesort

将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的。

EXPLAIN SELECT * FROM role ORDER BY create_time;

在这里插入图片描述

Select tables optimized away

使用某些聚合函数(比如 max、min)来访问存在索引的某个字段。

EXPLAIN SELECT MIN(id) FROM role;

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDFS最基础使用

文章目录 一、简介1、定义2、HDFS优缺点3、HDFS组成架构4、HDFS文件块大小 二、HDFS的读写流程1、HDFS写数据流程2、HDFS读数据流程3、网络拓扑-节点距离计算4、机架感知&#xff08;副本存储节点选择&#xff09; 三、NameNode和SecondaryNameNode1、NN和2NN工作机制2、Fsimag…

Linux关于gittee的远端仓库的连接和git三板斧

目录 1.网页操作 2.Linux操作 查看Linux系统中是否安装git指令 安装git指令 链接远端仓库 设置 .gitignore文件 3.git三板斧 1.网页操作 首先我们要在gittee建立一个仓库 这是我自己的勾选方案&#xff0c;大家可以参考一下。 这个方案勾选最下面的三个选项才有&#x…

java图书管理系统

一、 引言 图书管理系统是一个用于图书馆或书店管理图书信息、借阅记录和读者信息的应用程序。本系统使用Java Swing框架进行开发&#xff0c;提供直观的用户界面&#xff0c;方便图书馆管理员或书店工作人员对图书信息进行管理。以下是系统的设计、功能和实现的详细报告。 二…

最新整理源码面试题

经典框架源码面试题 Lecture&#xff1a;波哥 1.谈谈你对框架的理解 1.1 框架的作用 JavaWeb中的框架是一种开发工具或者平台&#xff0c;它提供了一系列的功能和组件&#xff0c;用于简化和加速Web应用的开发过程。框架可以提供一些基础设施&#xff0c;如数据库访问、用户认…

ISP图像信号处理——白平衡校正和标定介绍以及C++实现

从数码相机直接输出的未经过处理过的RAW图到平常看到的JEPG图有一系列复杂的图像信号处理过程&#xff0c;称作ISP&#xff08;Image Signal Processing&#xff09;。这个过程会经过图像处理和压缩。 参考文章1&#xff1a;http://t.csdn.cn/LvHH5 参考文章2&#xff1a;htt…

基于蜉蝣优化的BP神经网络(分类应用) - 附代码

基于蜉蝣优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于蜉蝣优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.蜉蝣优化BP神经网络3.1 BP神经网络参数设置3.2 蜉蝣算法应用 4.测试结果&#xff1a;5.M…

AAD基础知识(identity/token/PRT)

简介 AAD(Azure Active Directory/Azure AD)是微软基于云身份验证和访问控制的解决方案&#xff0c;通过SSO登录其他o365应用(word/outlook/teams…) 微软在2023年7月把AAD重命名为Microsoft Entra ID&#xff0c;官网&#xff1a;https://www.microsoft.com/zh-cn/security/b…

【多任务案例:猫狗脸部定位与分类】

【猫狗脸部定位与识别】 1 引言2 损失函数3 The Oxford-IIIT Pet Dataset数据集4 数据预处理4 创建模型输入5 自定义数据集加载方式6 显示一批次数据7 创建定位模型8 模型训练9 绘制损失曲线10 模型保存与预测 1 引言 猫狗脸部定位与识别分为定位和识别&#xff0c;即定位猫狗…

通过 HelpLook ChatBot AI自动问答机器人降低客户服务成本

在当今竞争激烈的商业环境中&#xff0c;提供卓越的客户服务对于维持忠诚的客户群和推动业务增长至关重要。客户服务涵盖了公司与其客户之间的所有互动&#xff0c;包括解答问题、解决问题和提供支持。它在塑造客户对品牌的看法方面起着关键作用&#xff0c;并且可以显著影响他…

C语言判断语句

判断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&#xff09;。 C 语言把任何非零和非空的值假定为 true&#xff0c;把零或 null 假定为 false。 下面…

react create-react-app v5 从零搭建(使用 npm run eject)

前言&#xff1a; 好久没用 create-react-app做项目了&#xff0c;这次为了个h5项目&#xff0c;就几个页面&#xff0c;决定自己搭建一个&#xff08;ps:mmp 好久没用&#xff0c;搭建的时候遇到一堆问题&#xff09;。 我之前都是使用 umi 。后台管理系统的项目 使用 antd-…

DevExpress ChartControl 画间断线

效果如下&#xff1a; 解决办法&#xff1a;数据源间断位置加入double.NaN demo下载

动态链接那些事

1、为什么要动态链接 1.1 空间浪费 对于静态链接来说&#xff0c;在程序运行之前&#xff0c;会将程序所需的所有模块编译、链接成一个可执行文件。这种情况下&#xff0c;如果 Program1 和 Program2 都需要用到 Lib.o 模块&#xff0c;那么&#xff0c;内存中和磁盘中实际上就…

Sui第五轮资助: 17个项目共获105万美元资助金

近日&#xff0c;Sui基金会宣布17个项目获得了105万美元的资助&#xff0c;用于建设项目以推动Sui的采用和发展。要获得资助&#xff0c;项目必须提交详细的提案&#xff0c;说明构建的项目、预算明细、关键里程碑、团队经验&#xff0c;以及对Sui社区的预期贡献。了解更多Sui资…

Azure Arc 概要:功能、管理和应用场景详解,AZ900 考点示例

文章目录 本文大纲一、什么是 Azure Arc二、使用 Azure Arc 可以做什么操作三、使用 Azure Arc 可以管理什么资源3.1 如何使用Azure Arc与服务器? 四、Azure Arc 支持的主要场景五、在 AZ900 中的考点示例5.1 示例题 15.2 示例题 2 本文大纲 本文思维导图概述的主要内容&…

已解决 Bug——IndexError: index 3 is out of bounds for axis 0 with size 3问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

软件工程与计算总结(二)软件工程的发展

本章开始介绍第二节内容&#xff0c;主要是一些历史性的东西~ 一.软件工程的发展脉络 1.基础环境因素的变化及其对软件工程的推动 抽象软件实体和虚拟计算机都是软件工程的基础环境因素&#xff0c;它们能从根本上影响软件工程的生产能力&#xff0c;而且是软件工程无法反向…

十四天学会C++之第三天(数组和字符串)

1. 数组的定义和初始化 数组是一种由相同数据类型的元素组成的集合&#xff0c;这些元素按照一定的顺序存储在连续的内存位置上。数组的大小在创建时是固定的&#xff0c;无法在运行时改变。 在C中&#xff0c;数组的定义和声明非常简单。定义一个数组&#xff1a; 数据类型…

vtk 动画入门 1 代码

实现效果如图&#xff1a; #include <vtkAutoInit.h> //VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //VTK_MODULE_INIT(vtkRenderingFreeType); #in…

IDEA Rogstry中找不到compiler.automake.allow.when.app.running问题解决

网上大部分人教我们 先 File > Settings 然后 勾选 Build 下的 Compiler中的 Build project automatically 这些步骤都不会有问题 然后就会让我们 ctrl shift alt / 点 Rogstry 打开后 我人就麻了 根本没有什么 compiler.automake.allow.when.app.running 也不用慌 我们…