MySQL优化Explain命令简介(二)
type列
MySQL手册上注明type列用于描述join type,不过我们认为把这一列视为对access type--即MySQL决定如何在表中寻找数据的方式的描述,更加合适一些,以下所示从最坏情况到最好情况下的access类型:
ALL
All类型即常说的全表扫描,通常意味着MySQL需要从头到尾扫描整张表以找到符合条件的行记录(使用LIMIT限定的查询语句个例外,一般在extra列中会有"Using distinct/not exists"的补充描述)。
index
基本和全表扫描一样,但是是通过索引的顺序扫描,主要优化是避免了排序,最大的缺点是通过索引顺序扫表时,通常意味着从存储空间中乱序取数据,IO花销会非常大。
如果在Extra列中还有"Using index"的说明,意味着MySQL使用一个覆盖索引实现扫表,而不是使用索引顺序扫表,这会比通过索引顺序扫表具有更好的性能。
range
一个范围遍历是一个限制版本的索引遍历,从索引中的某个位置开始,返回一定范围内的所有行记录,这会比扫描整个索引更快,这类查询的where子句中一般伴有BETWEEN或者>这类关键词。
当MySQL使用索引查找IN或者OR包含的一系列值时,也会显示为一个范围遍历,但是这两种其实是非常不同的访问类型,两者之间有着重要的性能差异。
ref
这是一个返回匹配特定单一值行记录的索引访问(索引查找)类型,实际上由于可能存在多行匹配的情况,这是一个查找和遍历的混合类型。这种索引查找仅能用于非唯一索引或者一个唯一索引的非唯一前缀索引。之所以叫做ref类型是因为索引被用于和一些参考值(reference value)进行比较,参考值只能一个常量或者多表查询中之前一个表中的某个值。
ref_or_null是ref的一个变种,意思是MySQL在做了第一次查找后,还必须做第二次查找查找为NULL的记录。
eq_ref
这是MySQL知道最多只会返回一个匹配结果的索引查找类型。当针对主键或者唯一索引和一些引用值比较时,就是这种访问类型,MySQL能针对这种类型做非常好的优化,因为不需要预估匹配行记录的范围或者在找到一行记录后再继续查找。
const,system
当MySQL能够将查询中的某些部分优化为一个常量时,就是这中访问类型。如果你将主键放置在where子句中,同时在select部分选取该主键,MySQL就会将其转化为一个常量,然后从join执行中高效的移除这个表。
NULL
NULL访问类型标识MySQL在优化阶段就能解析查询,甚至不需要在执行阶段实际访问到表数据或者索引,例如从索引列中获取最小值,只需要查看一下索引,不要求执行期间访问任何表数据。
possible_keys列
这一列基于查询语句中访问到和用于比较操作的列名,展示那些可能用于查询的索引名称列表,这个列表在优化阶段的早期生成,所以在经过后面的优化阶段后,其中的一些索引可能就并不需要用到了。
key列
这一列展示MySQL实际使用哪个索引优化对于表的访问,如果这个索引没有出现在possible_keys中,表明MySQL是基于其他特殊理由选定的该索引--比如即便查询没有where子句,MySQL也可能会优先选择使用覆盖索引。
换句话所,possible_keys揭示了哪些索引能够帮助行记录查询更加高效,而key则显示了优化器实际决定使用来最小化查询花销,下面是一个实际例子。
key_len列
这一列展示MySQL使用的索引的长度(字节个数),如果MySQL只使用索引中的一部分列,可以通过这个值计算出MySQL实际使用的是哪些列。注意MySQL5.5及以下版本只能使用最左前缀匹配。下面这个例子中sakila.film_actor的主键包括两个SMALLINT列,一个SMALLINT是两个字节,所以主键索引长度应该是4字节:
根据key_len,我们能推断出上面的查询语句仅在第一列(actor_id)上使用了索引查找。当计算列使用情况时,还需要考虑到字符类型列字段实际使用的字符集:
上面查询中a列和b列组成的索引长度为13字节,a列只有三个字符大小,但是utf8字符集使用最多3个字节标识一个字符,b列则是4字节整数。
MySQL并不总是会告诉你一个索引被多大程度使用到,如果你使用一个前缀匹配的LIKE查询,它将显示被使用那一列的总长度。
key_len列标识索引字段可能被使用到的最大长度,而不是表中数据使用的实际字节数量,即便上面的列a凑巧不包含任何长度大于一字符的值,MySQL依然会显示13字节长度,也就是说,key_len是通过表的定义计算得出,而非表中的实际数据。
ref列
这字段标识之前的表中哪些列或者常量被用于key列中的索引进行查找,下面是一个join和alias使用的例子,注意ref列反映了film表在查询语句中怎么被别称为f:
rows列
这一列展示MySQL估计查询语句执行时需要实际读取数据的记录行数,针对一个多重嵌套查询的语句,这个数字并不只是MySQL认为他需要从表中读取的实际行数,它将是每一个子查询阶段中MySQL估计满足当前查询条件所需要读取的行数。
根据表的统计信息已经索引的选择情况,这个估计可能很不准,MySQL5.0及以前,不会考虑LIMIT的影响,如下例:
你可以通过将每一行中这列的值相乘以得到整个查询语句大概要检查的行记录数量,如下例大概会检查2600行记录:
注意这个数量是MySQL估计会检查的行数,并不是结果集中的行数,并且诸如连接缓存这些优化,并不会影响到这一行的数值,即便MySQL可能并不会实际检查它估计的每一行数据,MySQL也不知道操作系统或者硬件缓存所做的任何优化。
filtered列
当使用EXPLAIN EXTENDED时,MySQL5.1及以上版本会有这一列,它针对满足where语句或者join条件的行数百分比做一个悲观估计,如果将rows列的数值乘以这个百分比,可以得到MySQL估计其会与前面的表数据进行join的行数量,优化器使用这一估计应用于ALL/index/range和index_merge访问类型。
假设下面一个标结构:
往表中插入1000条filler为随机的文本数据,以避免MySQL会针对我们的查询使用覆盖索引:
MySQL本可以使用一个range access通过ID从表中检查ID<500的行记录,但是考虑到这只能优化大概一半的行访问,它认为一个全表扫表的花销反而更少些,于是MySQL选择全表扫表时通过WHERE子句中的条件过滤行记录。通过range access的估计,MySQL能知道大概有多少行会被WHERE条件过滤,于是filtered列中的值就是49.40%了。
Extra列
这一列展示了其他列所没有的额外信息,MySQL文档上说明了能够出现在这一列的大多数值,你能够经常见到的最重要的一些取值如下:
Using index
MySQL会使用覆盖索引避免直接访问表数据,不要把覆盖索引和index访问类型弄混。
Using where
MySQL把数据从存储引擎中检索出来后,才会使用where条件进行过滤,WHERE子句中涉及到索引列的条件很多都可以在读取索引时被检测,所以并不是所有有WHERE子句的查询都会有“Using where”这一信息,有时候这个信息的存在暗示查询可能能够通过不同的索引策略获得优化。
Using temporary
MySQL会使用改一个临时表存储查询结果。
Using filesort
MySQL会对使用外部排序对结果排序,而不是通过索引顺序读取表数据,MySQL有两种filesort算法,都可以在内存或者硬盘上进行排序,EXPLAIN并不会指出具体使用的是哪种filesort算法,也不会指出是在内存还是硬盘上进行排序。
Range checked for each record(index map:N)
这意味着没有好的索引策略,join子句中的每一行都要重新计算索引,N表示possible_keys中的一个冗余的索引bitmap。
MySQL优化Explain命令简介(二)的更多相关文章
- MySQL优化Explain命令简介(一)
最近碰到MySQL需要写入大量数据并查询的场景,于是学习了一下MySQL的查询优化,想找关于explain命令的详细资料,然而网上并没有找全,最后终于在<高性能MySQL>中找到了对这一命 ...
- 一次浴火重生的MySQL优化(EXPLAIN命令详解)
一直对SQL优化的技能心存无限的向往,之前面试的时候有很多面试官都会来一句,你会优化吗?我说我不太会,这时可能很多人就会有点儿说法了,比如会说不要使用通配符*去检索表.给常常使用的列建立索引.还有创建 ...
- MySQL的EXPLAIN命令用于SQL语句的查询执行计划
MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提供任何调整建议,但它能够提供重要的信息 ...
- mysql优化——explain详解
MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提供任何调整建议,但它能够提供重要的信息 ...
- Windbg 脚本命令简介 二, Windbg command
Windbg 脚本命令简介 二, Windbg script command $<, $><, $$<, $$><, $$>a< (Run Scri ...
- MySQL 查询性能优化 - EXPLAIN 命令
查询优化的官方文档在 这里. EXPLAIN 的输出格式 译文 1. MySQL 架构 1.1 MySQL 的简化架构 MySQL 可以简单的分为三层:连接层.服务层.存储引擎层.其中服务层包含了 M ...
- MySQL的Explain命令
Explain命令是查看查询优化器如何决定执行查询的主要办法. 调用 EXPLAIN 要使用EXPLAIN,只需在查询中的SELECT关键字之前增加EXPLAIN.MySQL会在查询上设置一个 ...
- mysql优化:explain分析sql语句执行效率
Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...
- 【MySQL】EXPLAIN命令详解
具体参考: https://www.cnblogs.com/gomysql/p/3720123.html 原文如下: 在工作中,我们用于捕捉性能问题最常用的就是打开慢查询,定位执行效率差的SQL,那么 ...
随机推荐
- 远程调用内核接口的封装类(RCKObjs)
RCK 包括 Application, Function, Connection, Command, Response 和 Fields 六 大类, 其主要功能例如以下: a. Applica ...
- BZOJ4446:[SCOI2015]小凸玩密室(树形DP)
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室. 每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...
- 4、Spring Cloud-负载均衡 Ribbon
4.1.RestTemplate 简介 RestTemplate是Spring Resources中一个访问RESTful API 接口的网络请求框架. RestTemplate 的设计 则和其他 ...
- numpy初始化
一般的初始化就是用zeros这种去初始化,但你想测试一些函数的时候,如果是全0其实不好测试 可以先用python本身初始化一个list,然后转换成numpy的array a = [1.1,1.5,1. ...
- 非接触式读卡器13.56MHZ芯片:SI522
对于现在的智能锁市场需求竞争极大,中小型厂家月销量更是在慢慢增长.刷卡功能更是智能锁的标配功能,当然13.56Mhz芯片现在讲究的就是超低功耗,为满足市场需求专注于物联网多年的中科微强力推出了13.5 ...
- 修改linux系统的默认语言
修改linux系统的默认语言: 1.全局修改: 所有用户都是同一种统一的语言设置 修改/etc/sysconfig/i18n文件 vi /etc/s ...
- Gradle Goodness: Copy Files with Filtering
Gradle Goodness: Copy Files with Filtering Gradle's copy task is very powerful and includes filterin ...
- ext4文件系统特性浅析
ext4作为Linux下的文件系统因其简单性.易管理性.兼容性强等特定,深受大多数用户喜欢,并且作为大多数Linux发行版中的默认文件系统.但是随着现在文件数目的增多以及文件数据的增大,ext4文件系 ...
- nodejs中npm以及yarn常用指令
1.npm下载相关 1.npm install/i vue //下载vue的包 2.npm i vue --save-dev / -D //下载vue的包,并添加到开发依赖中 3.npm i //下载 ...
- mysql数据库用户密码管理
创建用户:create user 'oracle'@'localhost' identified by 'password'; MySQL 8以上:alter user 'root'@'localho ...