<<Mysql是怎样运行的>>小记-2

发布时间 2023-10-23 23:53:27作者: 况况况

第十章:单表访问方法

Mysql Server中又有一个叫优化器的模块,在Mysql服务端对一条查询语句进行语法解析之后,会将其再交给优化器来进行优化,在优化后会获得一个执行计划.
这个执行计划中表明了应该使用哪些索引查询,还有表之间的连接顺序等等.
最后会按照该执行计划中的步骤调用存储引擎提供的接口来真正的进行查询.

访问方法的概念

我们写的SQL查询语句只是告诉了MYSQL要查询出的数据要符合哪些规则,并不是限制了Mysql查询数据的方式.
同一个SQL查询语句,可能有多种获取到目标数据的方法,我们称这些方法为访问方法或是访问类型.虽然结果一样,但是不同的访问方法执行起来效率可能差距甚大.

接下来就来介绍一下各种访问方法

const

const访问方法指直接通过聚簇索引或是唯一二级索引直接定位到一条数据,意为常数级别,代价可以忽略不计.
不过该方法需要聚簇索引的主键值和唯一二级索引的主键值与某想查询的常数相等才能有效.如果某个唯一索引主键是多个列,需要该多个列都有指定的值才能有效.
如果是为NULL的情况下则const访问方法无效,因为可能查询到多条数据.

ref

当使用某个二级索引列与常数进行等值比较,ref访问方法就会有效.
select * from t where index='111'
搜索条件为二级索引列与常数进行等值比较,并且形成的扫描区间为单点区间,就比如[111,111].这种访问方法称为ref.
我们要注意:

  • 使用二级索引来进行查询,并不是查询完所有的数据再进行统一回表,而是查询到一条就进行一次回表.
  • 如果采用比较的列可以为NULL, 并且我们即使使用唯一索引来进行查询,使用 is NULL 作为条件,最多也只能使用ref访问方法,因为可能查询到多条数据
  • 对于联合索引来说,只要用于比较的是从左到右连续的索引列与常数比较,就可以使用ref访问方法.

ref_or_null

当使用某二级索引查询索引列与某常数相同的同时,还查询该索引列值为NULL的时候,使用的就是ref_or_null访问方法
select * from t where index='111' and index is NULL
扫描区间为[NULL,NULL]和[111,111]

range

之前的访问方法都是索引列与某常数值等值时有效的.
而range是:当使用某个索引执行查询时,形成的扫描区间为若干个单点扫描区或是范围扫描区,则为为range访问方法.
select * from t where index='111' OR (index>=30 AND index <=50)
注意:扫描区间只有一个单点扫描区或是扫描区为(-∞,+∞)时都不为range访问方法.

index

当查询的列都包含在某一索引中充当索引列,并且条件也在该索引列中,就会使用index访问方法
select part1,part2,part3 from t where part2='abc'
就比如这个查询语句,我们假设这个表有一个联合索引(part1,part2,part3).
虽然条件中的列并不是连续的,无法利用索引快速查询.
这个时候由于查询的列都在索引列中,所以不需要进行回表操作,而查询条件又在该索引列中.
所以只需要遍历该联合索引的全部记录,而后对条件进行判断即可.我们称这种访问方法为index

因为联合索引列中的记录大小比聚簇索引的小,所以这种方式成本会小很多.

注意:如果全表扫描的语句使用了ORDER BY 主键的语句,该语句也会被认为是index访问方法.

all

直接通过聚簇索引对全表的记录进行扫描,这种我们成为all访问方法.