三、mysql优化技术-执行计划

解决问题的一般思路是:发现问题,找到问题的原因,根据原因因地制宜解决。定位到了执行慢的sql语句后,接下来就要分析语句为什么执行慢。

mysql服务器执行sql语句是一个复杂的过程,大致流程如下:

1、接收客户端发送的sql语句;
2、对于查询语句,服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段;
3、进行SQL解析、预处理,在优化器生成对应的执行计划;
4、mysql根据优化器生成的执行计划,调用存储引擎的API来执行查询;
5、将结果返回给客户端。

也就是说,mysql服务器不是直接执行我们写的sql语句的,而是要对其进行优化,那如果能知道一些mysql优化的细节,对于我们寻找原因有很大帮助,mysql提供了查看执行计划的命令explain关键字,使用方法就是在执行的sql前加explain关键字,explain sql。

我们来看一条sql的执行:

 这条sql执行了4秒多,表结构如下:

表中总记录数如下:

 

查看一下这条sql语句的执行计划:

 

下表是个字段含义解释


字段
说明
可选值
id
查询序列号,表示查询中执行select子句或操作表的顺序
id相同,执行顺序由上至下,如果是子查询,id的序号会递增,
id值越大优先级越高,越先被执行  
一组数字
select_type
查询中每个select子句的类型 

SIMPLE:简单SELECT(不使用UNION或子查询)  

PRIMARY:包含复杂子部分时最外层查询

UNION:UNION中的第二个或后面的SELECT语句

DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询

UNION RESULT:从UNION表获取结果的SELECT

SUBQUERY:SELECT或WHERE列表中的子查询的第一个SELECT

DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询

DERIVED:FROM子句的子查询中包含UNION,外层SELECT

SIMPLE
PRIMARY
UNION

DEPENDENT UNION

UNION RESULT

SUBQUERY

DEPENDENT SUBQUERY

DERIVED

table

输出的行所引用的表

表名

type

联接类型,在表中找到所需行的方式

system:查询的表仅有一行数据

const:表最多有一个匹配行,如根据主键查询,或查询列有unique约束

eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行,它用在一个索引的所有

部分被联接使用并且索引是UNIQUEPRIMARY KEY

ref:非唯一性索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引或

唯一索引的非唯一前缀进行的查找

ref_or_null:ref,但是添加了MySQL可以专门搜索包含NULL值的行

index_merge:使用索引合并优化方法

unique_subquery:索引查找函数,可以完全替换子查询,效率更高

index_subquery:类似于unique_subquery,可以替换IN子查询

range:只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引

index:ALL相同,除了只有索引树被扫描,通常比ALL

ALL:全表扫描,遍历全表以找到匹配的行

从上至下,性能由高到低

system

const

eq_ref

ref

ref_or_null

index_merge

unique_subquery

index_subquery

range

index

ALL

possible_keys

指出MySQL能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,
则该索引将被列出,但不一定被查询使用 , 如果该列是 NULL ,则没有相关的索引
 

key

显示实际使用的索引,若没有使用索引,显示为NULL,
要想强制 MySQL 使用或忽视 possible_keys 中的 索引,在查询中使用
FORCE INDEX USE INDEX 或者 IGNORE INDEX  
 

key_len

显示mysql决定使用的键长度(字节数 )

 

ref

显示使用哪个列或常数与key一起从表中选择行

 

rows

表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数 
 

Extra

包含MySQL解决查询的详细信息
Distinct: 发现第 1 个匹配行后,停止搜索更多的行
Not exists: 对查询进行 LEFT JOIN 优化,发现 1 个匹配 LEFT JOIN 标准的行后,不再为
前面的的行组合在该表内检查更多的行
Using filesort:无法利用索引完成的排序操作
Using index:表示相应的select操作中使用了覆盖索引,MySQL可以利用索引返回select
列表中的字段,而不必根据索引再次读取数据文件,包含所有满足查询需要的数据的
索引称为覆盖索引
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询
Using where:使用where子句来过滤结果集

Distinct

Not exists

Using filesort

Using index

Using temporary

Using where

 回过头来看下之前的查询计划,这是一个对emp表的简单查询,没有使用索引,扫描全表,并使用where条件过滤结果集,查询到结果可能要扫描400万行记录。 已经找到了导致sql执行慢的一些地方,接下来就能有针对性的优化了。      

猜你喜欢

转载自ywu.iteye.com/blog/2314778