基于MySQL V6.0.0 alpha。
查询优化器,物理查询优化部分,涉及单表的扫描、两表的连接算法、多表连接方式和算法(左深树、紧密树、右深树和如greedy算法等)三个重要方面。之前,描述了多表连接的算法;如下,是单表扫描和两表连接中的重要点。
MySQL在greedy算法中,混合了启发式,利用如下规则,对查询做物理优化。
类型 | 代码表示方式[1] | 说明 |
system | JT_SYSTEM | 常量表情况一,表上没有元组或者只有一条元组 |
const | JT_CONST | 常量表情况二,表上有多条元组,但where子句条件限定符合条件的元组只有一条 |
eq_ref | JT_EQ_REF | 参与连接运算的表,是内表(在代码实现的算法中,两表连接时作为循环中的内循环遍历对象,这样的表为内表)。基于索引(连接字段上存在唯一索引或主键索引,且操作符必须是“=”谓词,索引的值不能为NULL)做扫描,使得对外表的一条元组,内表只有唯一一条元组与之对应 |
ref | JT_REF | 参与连接运算的表,是内表。基于索引(连接字段上的索引是非唯一索引,操作符必须是“=”谓词,连接字段值不可为NULL)做扫描,使得对外表的一条元组,内表只有若干条元组与之对应 |
ref_or_null | JT_REF_OR_NULL | 类似ref,只是连接字段的值可为NULL |
range | JT_RANGE | 基于索引做范围扫描,为诸如BETWEEN、IN、>=、LIKE类操作提供支持 |
index |
| 基于索引做扫描,但是基于索引做全部数据的扫描(扫描整个索引文件完成查询,不需要访问数据文件) |
ALL | JT_ALL | 不使用索引,顺序扫描,直接读取表上的数据(访问数据文件) |
| JT_UNIQUE_SUBQUERY | 在子查询中,基于唯一索引进行扫描 |
| JT_INDEX_SUBQUERY | 在子查询中,基于除唯一索引之外的索引进行扫描 |
index_merge | JT_INDEX_MERGE | 两表连接的每个表的连接字段上均有索引存在且索引有序 |
MySQL常量表的含义为:
1. 表中没有数据,或者只有一行数据(system类表)
2. 经where语句中的限制条件(“column = 常数”格式的表达式)筛选后只有一行数据;这表明,在column列上存在索引,索引列可能是一个主键列,或者是唯一键的列(constant表)
满足这2个条件之一的,就是常量表。
[1] 代码中的表示方式,可参考枚举类型“enum join_type”