本次测试使用的数据库版本为5.7 初始化sql语句:

CREATE TABLE `film` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;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 `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (1, 'a', '2017-12-02 15:27:18');
INSERT INTO `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (2, 'b', '2017-12-22 15:27:18');
INSERT INTO `xnyh`.`actor`(`id`, `name`, `update_time`) VALUES (3, 'c', '2017-12-22 15:27:18');INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (2, 'film 2');
INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (3, 'film0');
INSERT INTO `xnyh`.`film`(`id`, `name`) VALUES (1, 'film1');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);

先执行exlpain语句,EXPLAIN SELECT * from db,执行结果如下:

我们接下来对这12个字段依次进行解释

ID列

id列的值是代表了select语句执行顺序,是和select相关联的;id列的值大会优先执行,如果id列为空最后执行,id列相同,则从上到下依次执行。

select_type列

代表查询的类型,有如下几个值:

simple:

不包含子查询和join关键字 explain select * from film where id = 2;

primary:

复杂查询最外层select语句或者union语句中最左边的select explain select *,(select id from actor where id=1) from film

最外层查的是film表的,所以film对应的查询类型就是primary;

subquery:

仅限在from前面的select语句,不包括select后面的语句 explain select *,(select id from actor where id=1) from film

derived:

衍生表,如果from子句后面包含select语句,则会产生这种类型,它会把中间结果存放在临时表中,但是在5.7中需要使用set session optimizer_switch='derived_merge=off';关闭mysql对衍生表的合并优化,我们先看下不关闭之前,我们执行如下sql的情况: explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;

发现查询类型没有derived,我们关闭优化看下set session optimizer_switch='derived_merge=off'

发现出现了derived查询了,

union:

在 union 中的第二个和随后的 select explain select 1 union select 2 UNION select 3

table列

table列代表当前select语句正在查询哪张表。 EXPLAIN SELECT id from actor UNION select id from film

优先执行的是union后面的查询语句当前访问的是film表,接着执行union左边查询语句,当前查询的是actor表,最后查询的是依赖1和2的查询结果,所以使用<union1,2>来代替。

type列

type列的值分别为: NULL>system > const > eq_ref > ref > range > index > ALL; 执行效率依次递减。

NULL:

代表查询在mysql能够在优化阶段分解查询语句的时候直接能完成,不需要查询表和索引,例如获取逐渐最大列或最小列: EXPLAIN select min(id),max(id) from film

const:

当where后面是一个主键或者唯一索引 与一个常量精确比较时,mysql会把查询优化为常量查询,执行如下sql: explain select * from film where id = 2

我们可以看下mysql内部进行了如何优化: explain EXTENDED select * from film where id = 2; show WARNINGS;

可以看出mysql直接将其转换为常量进行查询

system:

如果要达到sysytem级别,那么它必须要达到以下几个条件:

1.是系统表或者是临时表 2.表中有且只有一条记录

  • 我在mysql库中找到了proxies_priv表,我们看执行如下sql: explain select * from proxies_priv

可以看出已经到了system级别;

  • 我们再看一种情况:派生表(临时表) explain extended select * from (select * from film where id = 1) tmp;

可以看到查询类型为PRIMARY已经达到了system级别,它是从派生表(临时表)中查询,并且派生表中只有一条记录,也能够达到system级别。

eq_ref:

主键或者唯一索引与其它表或字段进行关联查询,最多只会返回一条记录,如下代码: explain select * from film_actor left join film on film_actor.film_id = film.id;

可以看出访问film表的时候,type达到了eq_ref级别,因为id字段在film表中是唯一的,所以查询film表的时候按照id查询只会有一条记录与其关联;

ref:

相对于eq_ref,ref只需要要求是普通索引或者联合索引的前缀匹配

  • 普通索引查询explain select * from film where name = 'film1';
  • 联合索引前缀匹配 explain select film_id from film left join film_actor on film.id = film_actor.film_id;

range:

范围索引,通常为in、> < >= 这样的比较符,会达到range级别 explain select * from actor where id > 1;

index

扫描全表索引:所查询的列都创建了索引,但是没有按照索引字段过滤(除了让索引失效的操作除外) explain select * from film

all

扫描全表,通常情况下,是没有创建索引,需要增加索引优化 explain select * from actor;

possible_keys

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

key

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

key_len

该列记录了使用索引的长度,一般用来判断联合索引是否全部生效的作用,该值是根据不同数据类型进行计算的。

key_len计算规则如下:

  • 字符串

    • char(n):n字节长度
    • varchar(n):2字节存储字符串长度,如果是utf-8,则长度 3n + 2
  • 数值类型

    • tinyint:1字节
    • smallint:2字节
    • int:4字节
    • bigint:8字节
  • 时间类型
    • date:3字节
    • timestamp:4字节
    • datetime:8字节

如果字段允许为 NULL,需要1字节记录是否为 NULL 索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半 部分的字符提取出来做索引。

在创建表film_actor的时候我们已经创建了联合索引

KEY `idx_film_actor_id` (`film_id`,`actor_id`)

我们利用这个联合索引进行计算

  • 只使用联合索引的第一个字段: explain select * from film_actor where film_id = 2;

可以看到key_len是4,我们是根据联合索引字段的第一个字段进行过滤的,我们看下film_id字段的类型的int类型,结合上面的计算方式,file_id不能为NULL,那么key_len就是4;

  • 使用联合索引的两个字段: explain select * from film_actor where film_id = 2 and actor_id = 3

发现结果为8,这个因为这两个字段都是int类型,并且都不为NUll,那么加起来索引长度就是8,那就说明这个索引完全生效了。

ref

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

rows

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

Extra列

这个展示索引的额外信息,主要字段信息如下:

  • Using index 查询的字段被索引覆盖explain select film_id from film_actor
  • using where where 后面的字段没有使用被创建索引,优化方式,创建索引。 explain select film_id from film_actor where remark = '描述';
  • using index condition 查询的语句中,where条件中是一个前导列的范围; explain select * from film_actor where film_id = 1 and actor_id >3;
  • Using temporary 创建临时表,mysql查询过程中需要创建临时表来辅助查询,像这种情况是需要优化的。 explain select distinct name from actor;

通过给去重的字段添加索引,可达到优化的效果 CREATE index idx_name on actor(name)

方便后续测试,需要删除刚创建的索引:DROP INDEX idx_name on actor

  • Using filesort 数据排序的时候没有通过索引排序,当数据量小时通过内存排序,大的时候在磁盘中进行排序,需要进行索引优化,通常是排序字段没有创建索引。 explain select * from actor order by name;

下面的排序字段创建了索引,所以是在索引内进行排序 explain select * from film order by name;

  • Select tables optimized away 对某个创建了索引的字段查询使用了聚合函数 explain select max(id) from actor

未找到要求的 from 关键字_性能优化|这恐怕是解释Explain关键字最全的一篇文章相关推荐

  1. 未找到beta版怎么解决_刚刚,谷歌正式发布Android 11 Beta版,带来多项重磅更新...

    作者 | 安卓开发者博客 译者 | 核子可乐 策划 | 小智 转发链接:https://mp.weixin.qq.com/s/gp2XZGe69KDMAtsOeu56YA 前言 今日,谷歌安卓开发者博 ...

  2. oracle的优化适用于mysql吗_性能优化之数据库优化,适用于Sqlite、Mysql、Oracle、Sql server,详细介绍了索引和事务及部分针对Sqlite的优化...

    本文为性能优化的第一篇--数据库性能优化,原理适用于大部分数据库包括Sqlite.Mysql.Oracle.Sql server,详细介绍了索引(优缺点.分类.场景.规则)和事务,最后介绍了部分单独针 ...

  3. java线程太多卡顿_性能优化之卡顿延迟

    和你一起终身学习,这里是程序员 Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: 1.UI 渲染简介 2.识别延迟 3.Visual insp ...

  4. vue延迟渲染组件_性能优化之组件懒加载: Vue Lazy Component 介绍

    这篇文章分享了从遇到前端业务性能问题,到分析.解决并且梳理出通用的Vue 2.x 组件级懒加载解决方案(Vue Lazy Component )的过程. 初始加载资源过多 问题起源于我们的一个页面,下 ...

  5. 使用UE4开发VR项目_性能优化(一)_常用工具

    原作者:Mullin-ぼくリん <使用UE4开发VR项目-性能优化>系列文章将分成三篇分别介绍使用UE4开发VR项目的一些工具使用和VR优化思路.目的是总结UE4开发VR项目中常用的一些调 ...

  6. java transient关键字_小伙子,你真的搞懂 transient 关键字了吗?

    先解释下什么是序列化 我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术. Java序列化技术正是将对象转变成一串由二进制字节组成的数组,可以通过将 ...

  7. oracle sequences优化_性能优化-Oracle RAC中的Sequence Cache问题

    性能优化-Oracle RAC中的Sequence Cache问题 enq: SQ - contention 在RAC情况下,可以将使用频繁的序列Cache值增加到10000,或者更高到50000,这 ...

  8. mysql客户端工具_性能优化-理解 MySQL 体系结构(MySQL分库分表)

    实例和数据库 我们通常所说的 MySQL 数据库服务器由一个实例(instance)以及一个数据库(database)组成.实例包括一组后台进程/线程和许多内存结构,用于管理数据库:数据库由一组磁盘文 ...

  9. apache php 调优_性能优化之PHP优化

    一.语言级性能优化(一) PHP 性能问题的解决方向 PHP语言级别的性能优化 => PHP周边问题的性能优化 => PHP语言自身分析.优化 1.压力测试工具 Apache Benchm ...

最新文章

  1. postgresql如何实现group_concat功能
  2. MySQL的set names命令详解
  3. VMware NSX组件构建矩阵
  4. 什么才是Web前端开发的必备核心技能?
  5. python精确匹配字符串_Python: 字符串搜索和匹配,re.compile() 编译正则表达式字符串,然后使用match() , findall() 或者finditer() 等方法...
  6. linux主备dns切换时间,linux下主从DNS配置相关知识(二)
  7. 通过windows远程访问linux桌面的方法(简单)
  8. Atitit 前端 dom 的艺术 attilax著 目录 1. 概念 1 2. 发展历程 1 2.1. 厂商各自为政 2 2.2. 1.4 制定标准 标准化 w3cdom 2 2.3. 1.4.
  9. shop++ jtm2.5最新版本发布
  10. localhost:3000 拒绝访问解决办法
  11. JSON.stringify(value [, replacer] [, space])
  12. VSCode 配置 python环境 相对齐全 有遇到问题欢迎投稿哈
  13. R语言可视化散点图、ggrepel包的geom_text_repel函数避免数据点之间的标签互相重叠(设置segment.square为假以获得斜曲线,segment.inflect设置为真以引入拐点
  14. 技术之路也要懂得理财-------林左鸣:建设军工强国的5条锦囊妙计
  15. 游戏纽约夜生活java汉化_纽约玩乐--夜生活开启诱惑模式
  16. python画钢铁侠标志_pyecharts绘制复联超级英雄战斗力
  17. 错误1053: 服务没有及时地响应启动或控制请求
  18. 2019Java视频教程-Spring Boot实战
  19. CQL 函数及多深度关系节点
  20. Teamview 检测为商业用途

热门文章

  1. TXSQL企业级特性揭秘:加密与审计
  2. 使用ffmpeg视频切片并加密
  3. stun server、turn server、coturn server安装与使用
  4. ffplay播放没有声音SDL_OpenAudio (2 channels, 44100 Hz): WASAPI can't initialize audio client
  5. warning: control reaches end of non-void function
  6. Google Mock启蒙篇 [1] (Google C++ Mocking Framework for Dummies 翻译)
  7. Linux下axel多线程下载
  8. Puppet SaltStack Chef Ansible
  9. 使用Lombok简化开发及无效解决方案
  10. 【PAT甲级 最长公共子串】1007 Maximum Subsequence Sum (25 分) C++ 全部AC