MySQL2-Explain详解

这篇具有很好参考价值的文章主要介绍了MySQL2-Explain详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

❤️ 个人主页:程序员句号
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬+关注
🌸 订阅专栏:MySQL性能调优

MySQL性能优化专栏
1.MySQL性能优化1-MySQL底层索引结构
2.MySQL2-Explain详解
3.MySQL3-索引最佳实战
4.MySQL4-MySQL内部组件结构
5.MySQL5-事务隔离级别和锁机制
6.MySQL6-深入理解MVCC和BufferPool缓存机制

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连接查询,那么会输出两行
MySQL2-Explain详解

explain两个变种

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

type列

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

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

MySQL2-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;

MySQL2-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;

MySQL2-Explain详解

  • range:范围扫描通常出现在in(),between,>,<,>=等操作中,使用一个索引来检索给定范围的行。
mysql> explain select * from actor where id > 1;

MySQL2-Explain详解

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

MySQL2-Explain详解

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

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

MySQL2-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;

MySQL2-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;

MySQL2-Explain详解

  1. Using where:使用where语句来处理结果,并且查询的列未被索引覆盖
explain select * from actor where name = 'a';

MySQL2-Explain详解

  1. Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围
explain select * from film_actor where film_id > 1;

MySQL2-Explain详解

  1. Using temporary:MySQL需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想导用索引来优化。
    4.1 actor.name没有索引,此时创建一张临时表来distinct
explain select distinct name from actor;

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

explain select distinct name from film;

MySQL2-Explain详解

  1. Using filesort:将用外部排序而不是索引排序,数据较小时从内存排序,否则需要再磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的
    5.1 actor.name未创建索引,会浏览actor整个表,保存排序关键字name和对应的id,然后排序name并检索行记录
explain select * from actor order by name;

MySQL2-Explain详解
5.2 film.name建立了idx_name索引,此时查询时extra是using index

explain select * from film order by name;

MySQL2-Explain详解

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

MySQL2-Explain详解文章来源地址https://www.toymoban.com/news/detail-407919.html

到了这里,关于MySQL2-Explain详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • MySql 性能优化神器之 explain 详解

    MySql 性能优化神器之 explain 详解

    目录 一. 前言 二. explain 详解 2.1. 概念 2.2. 数据准备 2.3. id 2.3.1. id 相同,执行顺序由上至下 2.3.2. id 不同,数字越大优先级越高 2.3.3. id 存在相同的和不同的 2.4. select_type 2.5. table 2.6. partitions 2.7. type 2.7.1. system 2.7.2. const 2.7.3. eq_ref 2.7.4. ref 2.7.5. fulltext 2.7.6. ref_or_null 2.7.7. 

    2024年02月03日
    浏览(14)
  • Mysql中explain执行计划信息中字段详解

    Mysql中explain执行计划信息中字段详解

    2.1 id 每个select子句的执行顺序,相同从上到下,不同由大到小执行 2.2 select_type select语句类型 SIMPLE 简单的select查询,查询中不包含子查询或者UNION PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY SUBQUERY 在SELECT或WHERE列表中包含了子查询 DERIVED 在FROM列表中包

    2024年02月10日
    浏览(12)
  • Node第三方包 【mysql2】

    2023年04月23日
    浏览(10)
  • Nodejs使用mysql2操作数据库【完整讲解】

    mysql2 是一个基于 Node.js 的 MySQL 客户端库,相比于 mysql 库,它具有以下几个优势: 性能更好:mysql2 库在性能方面进行了优化,使用了更高效的底层实现。它使用了更快的连接池管理和查询执行机制,可以处理更高的并发请求,提供更好的性能表现。 支持 Promise 和 async/await:

    2024年02月02日
    浏览(20)
  • koa2 从0使用mysql2做第一个接口

    koa2 从0使用mysql2做第一个接口

    全局安装Koa命令行工具: npm install -g @koa/cli 2. 创建新项目: koa new my-app 这将生成如下目录结构: my-app ├── app.js ├── package.json └── src └── index.js 3. 安装依赖: cd my-app npm install 4. 启动项目: npm start 5.安装mysql2 yarn add mysql2 6.创建配置mysql连接池文件 7.在routes下面的文件使

    2024年02月16日
    浏览(11)
  • flink cdc MySQL2Doris 案例分享 解决分库多表同步

    使用flink cdc,完成mysql 多库 多表同时同步到doris中 flink 1.14.4 doris 1.1.0 flink-connector-mysql-cdc 2.2.1版本 一直会报异常 java.lang.NoClassDefFoundError: org/apache/flink/shaded/guava18/com/google/common/util/concurrent/ThreadFactoryBuilder 从官网下载依赖,然后本地添加进去flink-sql-connector-mysql-cdc-2.2.0 由于 U

    2023年04月09日
    浏览(13)
  • MySQL explain

    mysql explain(或desc)用于分析SQL语句的执行计划,多用于测试查询性能。语法:explain sql... explain执行DML语句,数据不发生变化。 explain执行的结果可以有多条数据,一条数据对应一个表,如果涉及union,MySQL内部会产生一个临时表,就会导致结果多一行数据。 union all不会创建临

    2024年03月09日
    浏览(9)
  • mysql explain 字段

    mysql explain 字段

    EXPLAIN SELECT *  FROM t_user2; EXPLAIN SELECT * FROM t_user2 WHERE user_name = \\\'r1\\\' CREATE INDEX index_username ON t_user2(user_name); EXPLAIN SELECT * FROM t_user2 WHERE user_name = \\\'test\\\'; EXPLAIN SELECT * FROM t_user2 WHERE user_name = CONCAT(user_name,\\\'01\\\'); 索引失效 EXPLAIN SELECT * FROM t_user2 WHERE user_name LIKE \\\'test\\\'; EXPLAIN SELECT * FROM t

    2024年03月26日
    浏览(11)
  • MySQL Explain分析

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

    2024年02月11日
    浏览(27)
  • MYSQL EXPLAIN 执行计划

    有了慢查询语句后,就要对语句进行分析。一条查询语句在经过 MySQL 查询优化器的各种基于成本和规则的优化会后生成一个所谓的执行计划,这个执行计划展示了接下来具体执行查询的方式,比如多表连接的顺序是什么,对于每个表采用什么访问方法来具体执行查询等等。

    2024年02月05日
    浏览(15)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包