MySQL数据库性能优化(2) (18)

SUBQUERY 和 DEPENDENT SUBQUERY:这两种类型都表示第一个查询是子查询。区别是SUBQUERY表示的子查询不依赖于外部查询,而后者的子查询依赖于外部查询。

UNCACHEABLE SUBQUERY:子查询结果不能被缓存, 而且必须重写(分析)外部查询的每一行

UNION:从第二个或者在union 之后的select 作为 union 查询。这种查询类型出现在结果集与结果集的UNION操作中。

UNION RESULT:结果集是通过union 而来的。这种查询类型出现在结果集与结果集的UNION操作中。

DEPENDENT UNION:从第二个或者在union 之后的select 作为 union 查询, 依赖于外部查询。这种查询类型出现在结果集与结果集的UNION操作中。

UNCACHEABLE UNION:第二个 或者 在UNION 查询之后的select ,属于不可缓存的查询。这种查询类型出现在结果集与结果集的UNION操作中。

5-2-2、type概要说明

执行计划的type列中,主要说明了子查询的执行方式。它的值可能有如下的这些项目(根据MySQL数据库的执行引擎和版本还会有一些其它选项):

ALL:全表扫描,实际上是扫描数据表的聚簇索引,并在其上加锁还会视事务隔离情况加GAP间隙锁。在数据量非常少的情况下,做全表扫描和使用聚簇索引检索当然不会有太大的性能差异。但是数据量一旦增多情况就完全不一样了。

index:进行索引进行的扫描,它和ALL一样都是扫描,不同点是index类型的扫描只扫描索引信息,并不会对聚簇索引上对应的数据值进行任何形式的读取。例如基于主键的函数统计:

# 以下语句还是要进行全表扫描,但是它并不需要读取任何数据信息。 explain select count(*) from myuser

1

2

range:在索引(聚簇索引和非聚簇索引都有可能)的基础上进行检索某一个范围内满足条件的范围,而并不是指定的某一个或者某几个值,例如:

# 以下查询语句在聚簇索引上检索一个范围 explain select * from myuser where id >= 10

1

2

ref:在非聚簇索引的基础上使用“非唯一键索引”的方式进行查找。例如:

# 在myuser中已基于user_name字段建立了非聚簇索引,且并非唯一键索引 explain select count(*) from myuser where user_name = \'用户1\'

1

2

const | system:const可以理解为“固定值”查询,常见于使用主键作为“简单查询”的条件时。system是比较特殊的const,当这个数据表只有一行的情况下,出现system类型。例如以下查询的操作类型就是const:

# 直接使用主键值就可以在索引中进行定位,无论数据量多大,这个定位的性能都不会改变 explain select * from myuser where id = 1

1

2

5-2-3、Extra概要说明

执行计划分析结果中的Extra字段,包含了结果中其他字段中没有说明但是对性能分析有非常有帮助的信息。甚至有的时候可以但从这个字段分析出某个子查询是否需要调整、涉及到的索引是否需要调整或者MySQL服务的环境参数配置是否需要进行调整。Extra字段还可以看成是对特定子查询的总结。

Using index:使用了索引(无论是聚簇索引还是非聚簇索引)并且整个子查询都只是访问了索引信息,而没有访问真实的数据信息,那么在Extra字段就会出现这个描述。请看如下示例:

explain select user_name from myuser where user_name = \'用户1\'; +--------+-------------------------------------+ | ...... | Extra | +--------+-------------------------------------+ | ...... | Using where; Using index | +--------+-------------------------------------+ # 使用user_name字段进行查询,原本需要再从聚簇索引中查找数据信息 # 但是InnoDB引擎发现只需要输出一个字段,且这个字段就是user_name本身,甚至不需要去找全部数据了。

Using where 和 Using index condition:此where关键字并不是SQL查询语句中的where关键字(此where非彼where),而是指该子查询是否需要依据一定的条件对满足条件的索引(全表扫描也是扫描的聚簇索引)进行过滤。示例如下:

# user_number 是一个非聚簇唯一键索引,所以where条件后的user_number只会定位到唯一一条记录 # 不需要再根据这个条件查询是否还有其它满足条件的索引项了 explain select * from myuser where user_number = 77777 +--------+-------------+ | ...... | Extra | +--------+-------------+ | ...... | | +--------+-------------+ # user_name 是一个非聚簇非唯一键索引,索引where条件后的user_name可能定位到多条记录 # 这时数据库引擎就会对这些索引进行检索,以便定位满足查询条件的若干索引项 #(由于B+树的结构,所以这些索引项是连续的) explain select * from from myuser where user_name = \'用户1\' +--------+------------------------------+ | ...... | Extra | +--------+------------------------------+ | ...... | Using index condition | +--------+------------------------------+

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgffsf.html