当前位置:

首页 > 编程开发 > MySQL之Explain怎么使用

MySQL之Explain怎么使用

Explain工具介绍使用Explain关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈。在select语句之前增加explain关键字,Mysql会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL注意:如果from中包含子查询,仍会执行该子查询,将结构放入临时表中示例代码DROPTABLEIFEXISTS`actor`;CREATETABLE`actor`(`id`int(11)NOTNULL,`name`varchar(45)DEFAULTNULL,`up

本文目录

    Explain工具介绍

    使用Explain关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈。在select语句之前增加explain关键字,Mysql会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL
    注意:如果from中包含子查询,仍会执行该子查询,将结构放入临时表中

    示例代码

    DROP TABLE IF EXISTS `actor`; 
    CREATE TABLE `actor` (
      `id` int(11) NOT NULL,
      `name` varchar(45) DEFAULT NULL,
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT INTO `actor` (`id`, `name`, `update_time`) VALUES (1,'a','2017-12-22 15:27:18'), (2,'b','2017-12-22 15:27:18'), (3,'c','2017-12-22 15:27:18');
    
    DROP TABLE IF EXISTS `film`;
    CREATE TABLE `film` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT INTO `film` (`id`, `name`) VALUES (3,'film0'),(1,'film1'),(2,'film2');
    
    DROP TABLE IF EXISTS `film_actor`;
    CREATE TABLE `film_actor` (
      `id` int(11) NOT NULL,
      `film_id` int(11) NOT NULL,
      `actor_id` int(11) NOT NULL,
      `remark` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `idx_film_actor_id` (`film_id`,`actor_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    INSERT INTO `film_actor` (`id`, `film_id`, `actor_id`) VALUES (1,1,1),(2,1,2),(3,2,1);

    explain select * from actor;

    在查询中的每个表都会输出一行,如果有两个表通过join连接查询,那么会输出两行

    MySQL之Explain怎么使用

    explain两个变种 explain extended

    会在explain的基础上额外提供一些查询优化的信息(5.7自动加上了,不需要这个命令了)紧随其后通过shouw warnings命令可以得到优化后的查询语句,从而看出优化器优化了什么。额外还有filtered列,是一个半分比的值。rows * filtered/100 可以估算出将要和explain中前一个表进行连接的行数。

    MySQL之Explain怎么使用

    explain partitions

    相比explain多了个partitions字段(5.7以后,explain默认有了),如果查询时基于分区表的话,会显示查询将访问的分区

    explain中的列

    接下来我们将展示 explain 中每个列的信息。

    id列

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

    select_type列

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

    1.simple:简单查询,不包含子查询和union

    2.primary:复杂查询中最外层的select

    3.subquery:包含在select中的子查询(不在from子句中)

    4.derived:包含在from自居中的子查询,MySQL会将结果存放在一个临时表中,也称为派生表

    mysql> set session optimizer_switch=‘derived_merge=off’; #关闭mysql5.7新特性对衍生表的合并优化

    mysql> explain select (select 1 from actor where id = 1) from (select * from film where

    id = 1) der;

    5.union:在union中的第二个和随后的select

    table列

    这一列表示explain的一行正在访问哪个表
    当from子句中有子查询时,table列时格式,表示当前查询依赖id=N的查询,于是先执行id=N的查询
    当有union时,union result的table列的值为 ,1和1表示参与union的select行id。

    type列

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

    一般来说得保证查询达到range级别,最大达到ref

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

    MySQL之Explain怎么使用

    • const,system:mysql能对查询的某部分进行优化并将其转换成一个常量(可以看show warnings的结果)。用于primary key 或 unique key的所有列与常数比较时,所以表最多有一个匹配行,读取一次,速度比较快。system时const的特例,表里只有一条元组匹配时为system。(意思就是system只有在数据找到一条的情况下出现)

     explain extended select * from (select * from film where id =1) tmp;

    MySQL之Explain怎么使用

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

    explain select * from film_actor left join film on film_actor.film_id = film.id;

    MySQL之Explain怎么使用

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

    1. 简单 select 查询,name是普通索引(非唯一索引)
    mysql> explain select * from film where name = 'film1';
    
    关联表查询,idx_film_actor_id是film_id和actor_id的联合索引,这里使用到了film_actor的左边前缀film_id部分。
    mysql> explain select film_id from film left join film_actor on film.id = film_actor.film_id;

    MySQL之Explain怎么使用

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

    mysql> explain select * from actor where id > 1;

    MySQL之Explain怎么使用

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

    explain select * from film;

    MySQL之Explain怎么使用

    为什么这里是走的idx_name这个索引?没有走主键索引?
    因为MySQL底层有一套判断使用哪个索引的机制,这里是因为这张表一共就2个字段,而这inx_name索引树就已经包含了id和name,这时候选择用主键和二级索引,它会优先选择二级索引因为它的索引树大小会小很多。
    如果有很多其他字段,可能会选择主键索引,因为你选择了二级索引还得做回表操作

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

     explain select * from actor;

    MySQL之Explain怎么使用

    possible_keys列

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

    key列

    这一列显示MySQL使用采用那个索引来优化对该表的访问。
    如果没有使用索引,则该列是NULL。如果想强制MySQL使用或忽视possibe_keys列中的索引,在查询中使用force index、ignore index。

    key_len列

    这一列显示了MySQL在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
    举例来说,film_actor的联合索引 idx_film_actor_id 由 film_id 和 actor_id 两个int列组成,并且每个int是4字节。通过结果中的key_len=4可推断出查询使用了第一个列:film_id列来执行索引查找。

    explain select * from film_actor where film_id = 2;

    MySQL之Explain怎么使用

    ref列

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

    rows列

    这一列是MySQL估计要读取并检测的行数,注意这个不是结果集里的行数

    Extra列

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

    • 1.Using index:使用覆盖索引 (不会回表)

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

    explain select film_id from film_actor where film_id = 1;

    MySQL之Explain怎么使用

    • 2.Using where:使用where语句来处理结果,并且查询的列未被索引覆盖

    explain select * from actor where name = 'a';

    MySQL之Explain怎么使用

    • 3.Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围

    explain select * from film_actor where film_id > 1;

    MySQL之Explain怎么使用

    1.Using temporary:MySQL需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想导用索引来优化。

    4.1 actor.name没有索引,此时创建一张临时表来distinct

    explain select distinct name from actor;

    MySQL之Explain怎么使用

    4.2 film.name创建了idx_name索引,此时查询时extra时using index ,没有用临时表

    explain select distinct name from film;

    MySQL之Explain怎么使用

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

    5.1 actor.name未创建索引,会浏览actor整个表,保存排序关键字name和对应的id,然后排序name并检索行记录

    explain select * from actor order by name;

    MySQL之Explain怎么使用

    5.2 film.name建立了idx_name索引,此时查询时extra是using index

    explain select * from film order by name;

    MySQL之Explain怎么使用

    6.Select tables optimized away:使用某些聚合函数(比如 max、min)来访问存在索引的某个字段

    explain select min(id) from film;

    MySQL之Explain怎么使用

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 MySQL
    相关文章 更多
    navicat导入数据库步骤详解及常见问题处理教程
    navicat导入数据库步骤详解及常见问题处理教程

    详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

    SQL主键约束和唯一约束有什么区别
    SQL主键约束和唯一约束有什么区别

    深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

    SQL约束有哪些类型及作用
    SQL约束有哪些类型及作用

    刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

    SQL游标常见错误排查:死锁与资源未释放问题
    SQL游标常见错误排查:死锁与资源未释放问题

    深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

    SQL中怎么创建和删除约束
    SQL中怎么创建和删除约束

    后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

    SQL分组统计查询:GROUP BY与HAVING子句用法示例
    SQL分组统计查询:GROUP BY与HAVING子句用法示例

    针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

    SQL Server与MySQL游标基本语法及完整代码示例
    SQL Server与MySQL游标基本语法及完整代码示例

    本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景
    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景

    深入解析SQL中INNER JOIN与LEFT JOIN的核心区别。通过users和orders表实例,展示匹配行保留与NULL补位机制,重点讲解ON与WHERE子句中放置右表过滤条件的不同后果,提供防止LEFT JOIN退化的实战技巧及行数异常排查步骤。

    SQL CHECK约束的用法与取值范围限制
    SQL CHECK约束的用法与取值范围限制

    深入理解 SQL CHECK 约束在 PostgreSQL、MySQL 等数据库中的实现差异。文章通过订单业务场景,讲解如何定义单列范围与多列逻辑约束,分析 NULL 值对布尔条件的影响,并提供修改已有表结构时的安全操作建议,帮助开发者构建更健壮的数据完整性防线。

    SQL外键约束怎么用及级联操作说明
    SQL外键约束怎么用及级联操作说明

    后端开发中,如何正确使用 SQL 外键约束来维护订单与明细表的关系?本文通过 PostgreSQL 示例,深入讲解外键的创建语法、插入顺序要求,以及 ON DELETE CASCADE、RESTRICT、SET NULL 等策略的实际影响与风险控制,助你构建健壮的数据库结构。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。