三、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:对于每个来自于前面的表的行组合,从该表中读取一行,它用在一个索引的所有 部分被联接使用并且索引是UNIQUE或PRIMARY 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 |
上一篇: SQL*LOADER操作篇
下一篇: MySQL 分区表举例