mysql explain优化索引及查询语句(explain介绍及使用实例)

时间:2016-10-04
mysql explain显示了MySQL如何使用索引来处理select语句以及连接表,explain 可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们查询,让查询优化器能够更好的工作。本文章向大家介绍mysql explain查询优化及使用实例,需要的朋友可以参考一下。

mysql explain可以帮助你检查索引和更好的优化查询语句,今天特地学习了下mysql explain的用法。

先解析一条sql语句,看出现什么内容

/** www.manongjc.com */
/** www.manongjc.com/article/1519.html */

EXPLAIN SELECT s.uid,s.username,s.name,f.email,f.mobile,f.phone,f.postalcode,f.address
FROM uchome_space ASs,uchome_spacefieldASf
WHERE 1 
AND s.groupid=0
AND s.uid=f.uid

得到结果:

mysql explain优化索引及查询语句

EXPLAIN列的解释:

id:选定的执行计划中查询的序列号。表示查询中执行select子句或操作表的顺序,id值越大优先级越高,越先被执行。id相同,执行顺序由上至下。

select_type:查询类型,说明:

select_type 查询类型 说明
SIMPLE 简单的 select 查询,不使用 union 及子查询
PRIMARY 最外层的 select 查询
UNION UNION 中的第二个或随后的 select 查询,不 依赖于外部查询的结果集
DEPENDENT UNION UNION 中的第二个或随后的 select 查询,依 赖于外部查询的结果集
SUBQUERY 子查询中的第一个 select 查询,不依赖于外 部查询的结果集
DEPENDENT SUBQUERY 子查询中的第一个 select 查询,依赖于外部 查询的结果集
DERIVED 用于 from 子句里有子查询的情况。 MySQL 会 递归执行这些子查询, 把结果放在临时表里。
UNCACHEABLE SUBQUERY 结果集不能被缓存的子查询,必须重新为外 层查询的每一行进行评估。
UNCACHEABLE UNION UNION 中的第二个或随后的 select 查询,属 于不可缓存的子查询

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL

  • all: full table scan ;mysql将遍历全表以找到匹配的行;
  • index : index scan; index 和 all的区别在于index类型只遍历索引;
  • range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值的行,常见与between ,< ,>等查询;
  • ref:非唯一性索引扫描,返回匹配某个单独值的所有行,常见于使用非唯一索引即唯一索引的非唯一前缀进行查找;
  • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常用于主键或者唯一索引扫描;
  • const,system:当mysql对某查询某部分进行优化,并转为一个常量时,使用这些访问类型。如果将主键置于where列表中,mysql就能将该查询转化为一个常量。

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:MYSQL认为必须检查的用来返回请求数据的行数

Extra:关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢。

下面来看那一下mysql explain在组合索引、慢查询分析、MYISAM和INNODB的锁定、MYSQL的事务配置项等方面的应用实例分析。

1.使用explain语句去查看分析结果 

explain select * from test1 where id=1;

会出现:id selecttype table type possible_keys key key_len ref rows extra各列。

使用explain语句去查看分析结果 

使用explain语句去查看分析结果 

其中, 

type=const表示通过索引一次就找到了; 

key=primary的话,表示使用了主键; 

type=all,表示为全表扫描; 

key=null表示没用到索引。

type=ref,因为这时认为是多个匹配行,在联合查询中,一般为REF。

2.MYSQL中的组合索引 

假设表有id,key1,key2,key3,把三者形成一个组合索引,则如: 

where key1=....   
where key1=1 and key2=2   
where key1=3 and key2=3 and key3=2 

根据最左前缀原则,这些都是可以使用索引的,如from test where key1=1 order by key3,用explain分析的话,只用到了normal_key索引,但只对where子句起作用,而后面的order by需要排序。

3.使用慢查询分析(实用)

在my.ini中: 

long_query_time=1 
log-slow-queries=d:\mysql5\logs\mysqlslow.log 

把超过1秒的记录在慢查询日志中 

可以用mysqlsla来分析之。也可以在mysqlreport中,又如 

DMS分别分析了select ,update,insert,delete,replace等所占的百分比

4.MYISAM和INNODB的锁定 

myisam中,注意是表锁来的,比如在多个UPDATE操作后,再SELECT时,会发现SELECT操作被锁定了,必须等所有UPDATE操作完毕后,再能SELECT
innodb的话则不同了,用的是行锁,不存在上面问题。 

5.MYSQL的事务配置项 

innodb_flush_log_at_trx_commit=1 

表示事务提交时立即把事务日志flush写入磁盘,同时数据和索引也更新,很费性能。

innodb_flush_log_at_trx_commit=0 

事务提交时,不立即把事务日志写入磁盘,每隔1秒写一次,MySQL挂了可能会丢失事务的数据。

innodb_flush_log_at_trx_commit=2 

在整个操作系统 挂了时才可能丢数据,一般不会丢失超过1-2秒的更新。

事务提交时,立即写入磁盘文件(这里只是写入到系统内核缓冲区,但不立即刷新到磁盘,而是每隔1秒刷新到磁盘,同时更新数据和索引),这种方案是不是性价比好一些,当然如何配置,决定于你对系统数据安全性的要求。