掌控你的MySQL语句执行方案
Posted lei子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了掌控你的MySQL语句执行方案相关的知识,希望对你有一定的参考价值。
SQL语句执行方案
在互联网项目中,必然少不了数据库的使用,随着服务器QPS的上升,数据库的性能逐渐成为产品发展的瓶颈,对于快速响应用户的操作请求,掌控SQL语句的执行方案,对于请求的快速响应、查询的性能提升有着举足轻重的作用。
互联网项目中,大部分情况下使用mysql数据库,查看查询优化器如何执行查询的主要方法是使用 EXPLAIN 命令。
EXPLAIN简介
从此简单示例中,可以看到 EXPLAIN 的输出列表,主要包含以下字段:
id - 查询编号,一般简单SELECT语句,编号为1,如有子查询时,则为顺序编号。
select_type - 显示SELECT是简单还是复杂。
table - 查询的数据表名或者表别名。
partions - 使用EXPLAIN PARTITIONS时出现,查询使用的分区
type - 查询关联类型
possible_keys - 查询可能使用的索引
key - 查询使用的索引
key_len - 索引使用的字节数
ref - 查询值所用的列或者常量
rows - 查询读取的行数
filtered - 使用 EXPLAIN EXTENDED时出现,显示针对表里符合某个条件的记录数的百分比所做的一个悲观估算
Extra - 不适合在其他列显示的额外信息
EXPLAIN显示的是近似值,可以从宏观层面大致显示查询的执行步骤、信息。
EXPLAIN使用
1. id
2. select_type
如果查询是简单类型,则EXPLAIN标记为SIMPLE,意味着查询不包含子查询和UNION;
如果查询是复杂类型,则EXPLAIN最外层部分标记为PRIMARY,而其他部分则为如下部分:
SUBQUERY
包含在SELECT列表中的子查询中的SELECT,如下查询中的ID为2的EXPLAIN行。
DERIVED
包含在FROM子句的子查询中SELECT,MySQL会递归执行并将结果放到一个临时表中。服务器内部称为派生表,因为临时表是从子查询中派生而来。
UNION
在UION查询中的第二个和随后的SELECT被标记为UNION。
UNION RESULT
用来从UNION的匿名临时表检索结果的SELECT被标记为UNION RESULT
UNION和UNION RESULT示例:
SUBQUERY和UNION可以被标记为:DEPENDENT、UNCACHEABLE。
DEPENDENT
意味着SEELCT依赖于外层查询中发现的数据
UNCACHEABLE
意味着SEELCT中的某些特性阻止结果被缓存于一个Item_cache中
3. table
此列显示对应行正在访问的数据表,通常情况下为表名或者表的别名。
表名或者别名
正常简单查询时,显示表名或者表别名
derivedN
表示派生表,其中 N 表示子查询的ID
union1,2
在UNION查询时,展示此数据,表示包含UNION 的id 列表
4. type
此列表示MySQL决定如何查找表中的行。按照性能从差到优的排序,依次如下:
1. ALL
MySQL扫描整张表,从头到尾查找需要的行。
2. index
和全表扫描一样,MySQL扫描表按照索引次序进行。
优点
避免了排序
缺点
需要承担按索引次序读取整个表的开销。
意味着若按照随机次序访问行,则查询开销会非常大。
3. range
SQL语句中带有BETWEEN或者WHERE子句里带有>的查询即为范围扫描。
4. ref
此类索引访问只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。
ref_or_null 意味着MySQL必须在初次查找的结果里进行第二次查找以找出NULL条目。
5. eq_ref
此类索引查找,MySQL知道最多只返回一条符合条件的记录。
SQL语句使用主键或者唯一性索引查找时显示。
6. const、system
当MySQL能对查询的某部分进行优化并将其转换成一个常量时,其就会使用此种访问类型,如下:
7. NULL
表示MySQL能够在优化阶段分解查询语句,在执行阶段甚至不用再次访问表或者索引。
5. possible_keys
显示查询过程中可以使用哪些索引,其基于查询访问的列和使用的比较操作符来进行判断。
6. key
如上查询,该查询使用了覆盖索引,key列有值,而possible_keys无值。
7. key_len
显示MySQL在索引里使用的字节数。
计算列的使用情况时,还需将字符列的字符集考虑进去。考虑下表
explain语句输出如下:
可以看到key_len为47,那么此47是如何获得的?计算方式如下:【15 * 3 + 2 = 47】
15 为phone列的字符串长度
3 为一个 utf8 字符占用的字节数(3个字节)
2 为varchar类型用于存储字符串长度占用的字节数
8. ref
显示之前的表在key列记录的索引中查找值所用的列或者常量。
9. rows
10. filtered
将rows列与此百分比相乘,就能看到MySQL估算将查询到的行数。
此列主要是MySQL在做范围查询时需要消耗的成本,MySQL在某些查询时,会根据此值判断使用索引或者全表扫描或者其他策略。
11. Extra
包含不适合在其他列显示的额外信息。
常见的信息如下:
Using index
表示查询使用覆盖索引,避免访问表。
Using where
表示MySQL服务器将在存储引擎检索行后在进行过滤。
Using temporary
表示MySQL对查询结果排序时使用了临时表。临时表可能存在内存或者磁盘中。
Using filesort
内存,数据量较小时,直接在内存中进行排序
磁盘,数据量较大时,使用磁盘进行排序
Range checked for each record(index map: N)
EXPLAIN限制
EXPLAIN不会解释触发器、存储过程或者UDF的执行方案;
UDF是mysql的一个拓展接口,UDF(Userdefined function)可翻译为用户自定义函数,这个是用来拓展Mysql的技术手段。
EXPLAIN 不会提供MySQL在查询执行中所做的特定优化;
不区分具有相同名字的事物,如filesort、Using temporary,并不区分查询发生在内存还是磁盘中;
可能存在一定的误导,如对于limit语句的查询显示全索引扫描。
[延伸阅读]
以上是关于掌控你的MySQL语句执行方案的主要内容,如果未能解决你的问题,请参考以下文章