坊间有传言:MySQL性能优化有个神器,叫做explain,它可以对select语句进行分析并且输出详细的select执行过程的详细信息,让开发者从这些信息中获得优化的思路。

下面来讲讲这个MySQL提供的explain命令:

语法:explain SQL语句
例如:

1explain select * from user where id=1
 执行完毕之后,它的输出有以下字段:

id
select_type
table
partitions
type
possible_keys
key
key_len
ref
rows
Extra
要想知道explain命名怎么使用,就必须把这些字段搞清楚

1. id
SELECT查询的标识符, 每个SELECT语句都会自动分配一个唯一的标识符

2. select_type
每个select查询字句的类型,具体类型以及对应作用如下表:

类型名 解释
SIMPLE 简单SELECT,不使用UNION或子查询等
PRIMARY 查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY
UNION UNION中的第二个或后面的SELECT语句
DEPENDENT UNION UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT UNION的结果
SUBQUERY 子查询中的第一个SELECT
DEPENDENT SUBQUERY 子查询中的第一个SELECT,取决于外面的查询
DERIVED 派生表的SELECT, FROM子句的子查询
UNCACHEABLE SUBQUERY 一个子查询的结果不能被缓存,必须重新评估外链接的第一行
3. table
显示这一行的数据是查哪张表的,不过有时短路显示的不是真实的表名。

4. partitions
匹配的分区(这个目前用处不大)

5. type
访问类型,表示MySQL在表中找到所需行的方式,对应的值和解释如下:

类型名 优级别 解释
system 1 表仅有一行
const 2 表最多有一个匹配行,在查询开始时即被读取
eq_ref 3 使用primary key或者unique key作为多表连接的条件,仅从该表中读取一行
ref 4 作为查询条件的索引在每个表匹配索引值的行从表中读取出来
fulltext 5 全文索引检索
ref_or_null 6 和ref一致,但增加了NULL值查询支持
index_merge 7 表示使用了索引合并优化方法
unique_subquery 8 使用了替换了in子查询
index_subquery 9 使用了替换了in子查询,但只适用于子查询中的非唯一索引
range 10 只检索给定范围的行,使用一个索引来选择行
index 11 全表扫描,但扫描表的方式是按索引的次序进行
ALL 12 全表扫描的方式找到匹配的行
type作为访问类型,其值代表着当前查询所用的类型,是体现性能的一个重要指标,从表中可以看到,从上到下,扫描表的方式越来越宽,性能也就越来越差,因此,对于一个查询,最好能保持在range级别以上。

6. possible_keys
主动指出查询能用哪个索引在表中找到记录
也就是会列出在查询中的字段中有索引的字段,但不一定被查询所用。

7. key
显示再查询中实际使用的索引/键,如果没有索引,则显示NULL。
但如果想强制查询中使用或忽视possible_keys列中的索引,则可以在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

8. key_len
表示索引中使用的字节数。

9. ref
表示哪些列或常量被用于查找索引列上的值。

10. rows
显示当前查询估算到的查找到匹配记录所需的记录行数。

11. Extra
显示当前查询所用的解决方式,它有以下几种情况:

类型名 解释
Using where 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,
Using temporary 表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using filesort MySQL中无法利用索引完成的排序操作称为“文件排序”
Using join buffer 改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Impossible where 这个值强调了where语句会导致没有符合条件的行。
Select tables optimized away 这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
讲完了语法,我们来实际操作一波,首先创建个表:

1-- 创建表
2CREATE TABLE test(
3id INT(11) NOT NULL AUTO_INCREMENT,
4uname VARCHAR(255),
5PRIMARY KEY(id) 
6);
复制代码
然后给uname字段加上索引:

1-- 添加索引
2ALTER TABLE test ADD INDEX uname_index (uname);
复制代码
查看一下索引是否添加成功:

1-- 查看是否有索引
2SHOW INDEX FROM test;
复制代码
输出结果为:

可以看出索引已经创建成功,接下来添加一些数据:

1-- 添加一些数据
2INSERT INTO test VALUES(1,'jay');
3INSERT INTO test VALUES(2,'ja');
4INSERT INTO test VALUES(3,'bril');
5INSERT INTO test VALUES(4,'aybar');
复制代码
一切准备就绪,下面用explain这个命令来探究一些like语句是否有索引,
like有四种情况,分别为没有%、 %% 、左%、右%、

1. like 字段名
1EXPLAIN SELECT * FROM test WHERE uname LIKE 'j'; 
复制代码
输出为:

可以看出:
type的值为:range,key的值为uname_index,也就是说这种情况下,使用了索引。

2. like %字段名%
1EXPLAIN SELECT * FROM test WHERE uname LIKE '%j%'; 
复制代码
输出为:

可以看出:
type的值为ALL也就是全表扫描,而且key的值为NULL,也就是说没用到任何索引。

3. like %字段名
1EXPLAIN SELECT * FROM test WHERE uname LIKE '%j'; 
复制代码
输出为:

可以看出:
type的值为ALL,key的值为NULL,同样没用到索引。

4. like 字段名%
1EXPLAIN SELECT * FROM test WHERE uname LIKE 'j%'; 
复制代码
输出为:

可以看出:
type的值为:range,key的值为uname_index,也就是说这种情况下,使用了索引。

5. 用其他方法实现:LOCATE('substr',str,pos)方法
SELECT LOCATE('xbar',`foobar`);
###返回0

SELECT LOCATE('bar',`foobarbar`);
###返回4

SELECT LOCATE('bar',`foobarbar`,5);
###返回7
备注:返回 substr 在 str 中第一次出现的位置,如果 substr 在 str 中不存在,返回值为 0 。如果pos存在,返回 substr 在 str 第pos个位置后第一次出现的位置,如果 substr 在 str 中不存在,返回值为0。

SELECT `column` FROM `table` WHERE LOCATE('keyword', `field`)>0
备注:keyword是要搜索的内容,field为被匹配的字段,查询出所有存在keyword的数据

5.2 FIND_IN_SET(str1,str2)方法
返回str2中str1所在的位置索引,其中str2必须以","分割开。

SELECT * FROM `person` WHERE FIND_IN_SET('apply',`name`);

总结
由上面的试验可以总结出like是否使用索引的规律:
like语句要使索引生效,like后不能以%开始,也就是说 (like %字段名%) 、(like %字段名)这类语句会使索引失效,而(like 字段名)、(like 字段名%)这类语句索引是可以正常使用,也可以换LOCATE的写法、FIND_IN_SET

其它
为了查证like索引的问题,研究了MySQL神奇explain,但explain不仅仅只能检查索引使用情况,还可以提供很多其它的性能优化方面的帮助,至于具体的使用,其实跟上面讲的一样,把explain结果列出来,然后顺藤摸瓜查阅相关的字段就可以得到相应的内容。

---------------------
作者:T&K
来源:CSDN
原文:https://blog.csdn.net/sinat_41780498/article/details/83024781
版权声明:本文为博主原创文章,转载请附上博文链接!

explain SQL语句()的更多相关文章

  1. explain SQL语句性能检测

    一般用来分析sql语句如何执行,使用了那些键 mysql>explain select * from table;+----+-------------+-------+------+----- ...

  2. mysql explain 分析sql语句

    鉴于最近做的事情,需要解决慢sql的问题,现补充一点sql语句性能分析之explain的使用方式! 综合返回数据情况,分析各个参数,可以了解sql 使用方法:explain  + sql语句 如 :e ...

  3. mysql分析sql语句基础工具 -- explain

    分析sql语句 explain explain (sql语句) G; 分析结果: id sql语句编号如果是连接查询,表之间是平等关系,编号相同:如果有子查询,编号递增. select——type 查 ...

  4. MYSQL学习笔记——sql语句优化工具

    优化sql:思路: 使用explan->先查询type类型看看是all还是ref,然后判断 possible_keys (显示可能应用在这张表中的索引, 一个或多个.查询涉及到的字段是若存在索引 ...

  5. mySQL数据库Sql语句执行效率检查--Explain命令

    mysql性能的检查和调优方法 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的 ...

  6. mysql优化(三)–explain分析sql语句执行效率

    mysql优化(三)–explain分析sql语句执行效率 mushu 发布于 11个月前 (06-04) 分类:Mysql 阅读(651) 评论(0) Explain命令在解决数据库性能上是第一推荐 ...

  7. EXPLAIN PLAN获取SQL语句执行计划

    一.获取SQL语句执行计划的方式 1. 使用explain plan 将执行计划加载到表plan_table,然后查询该表来获取预估的执行计划 2. 启用执行计划跟踪功能,即autotrace功能 3 ...

  8. mysql优化:explain分析sql语句执行效率

    Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优 ...

  9. SQL 语句 explain 分析

      分析索引的效率: > EXPLAIN sql; EXPLAIN 分析的结果的表头如下: id | select_type | table | partitions | type | poss ...

随机推荐

  1. mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高

    mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高 在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ... ...

  2. 分享知识-快乐自己:Liunx 根目录结构

  3. Memcached 分布式缓存实现原理简介

    摘要 在高并发环境下,大量的读.写请求涌向数据库,此时磁盘IO将成为瓶颈,从而导致过高的响应延迟,因此缓存应运而生.无论是单机缓存还是分布式缓存都有其适应场景和优缺点,当今存在的缓存产品也是数不胜数, ...

  4. webpack打包APP的后端地址处理

    PC端我们用webpack打包,只需要写相对路径,发布的时候和后端接口在同一目录下即可. 但是做过APP或者混合开发的同学都知道,APP不需要发布的,如果后端地址还是用相对路径的话,可想而知,调用后端 ...

  5. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  6. 2.2synchronized同步语句块

    使用synchronized虽然能够避免不同步的现象出现,但是也会出现弊端,比如代码执行时间过长,那么其他线程就必须等待该线程执行完毕释放锁之后才能拿到锁. 面对这种问题可以使用同步代码块来解决. 2 ...

  7. java内存模型(netty权威指南)

    1.Java内存模型 Java虚拟机规范中试图定义一种java内存模型(java Memory Model,jmm)来屏蔽掉各种操作系统.虚拟机实现厂商和硬件的内存访问差异,以确保Java程序在所有操 ...

  8. linux获取文件大小的函数

    C语言fstat()函数:由文件描述词取得文件状态 头文件:#include <sys/stat.h>   #include <unistd.h> 定义函数:int fstat ...

  9. Ruby 局部变量做block参数

    Ruby中使用yield语句调用block时可以带有参数,参数值见传送个相关联的block.如果传给block的参数是已经存在的局部变量,那么这些变量即为block的参数,他们的值可能会因block的 ...

  10. Linux 文件名颜色

    在Linux中,文件的颜色都是有含义的.其中, 蓝色表示目录 绿色表示可执行文件 红色表示压缩文件 浅蓝色表示链接文件 灰色表示其它文件 红色闪烁表示链接的文件有问题了 黄色是设备文件,包括block ...