思考题
以下两条SQL语句,那个执行效率高? 为什么?
A. select * from user where id = 10 ;
B. select * from user where name = 'Arm' ;
备注: id为主键,name字段创建的有索引;
解答: A 语句的执行性能要高于B 语句。
因为A语句直接走聚集索引,直接返回数据。 而B语句需要先查询name字段的二级索引,然 后再查询聚集索引,也就是需要进行回表查询。
在说详细解析回表查询之前,我们先了解一下索引的分类
索引分类(按照类型分类)
- 主键索引
- 唯一索引
- 常规索引
- 全文索引
| 分类 | 含义 | 特点 | 关键字 |
|---|---|---|---|
| 主键索引 | 针对表中主键建立的索引 | 默认自动创建,只能有一个 | PRIMARY |
| 唯一索引 | 避免某一列中的数据重复 | 可以有多个 | UNIQUE |
| 常规索引 | 快速定位特定数据 | 可以有多个 | |
| 全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
聚集索引选取规则:
- 如果存在主键,主键索引就是聚集索引
- 如果不存在主键,将使用第一个唯一(unique)索引作为聚集索引
- 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引
聚集索引&二级索引(按照存储形式分类)
| 分类 | 含义 | 特点 |
|---|---|---|
| 聚集索引 | 将数据与索引存储在一块,索引结构的叶子节点保存了行数据 | 必须有,且只能有一个 |
| 二级索引 | 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 | 可以存在多个 |
- 聚集索引的叶子节点下挂的是这一行的数据
- 二级索引的叶子节点挂的是该字段值对应的主键值
单列索引与联合索引(按照索引涉及到的列进行分类)
单列索引:即一个索引只包含单个列。
联合索引:即一个索引包含了多个列。
回表查询
SELECT * FROM TEST WHERE name = 'Arim'
- 由于是根据name字段进行查询,所以先根据name='Arm'到name字段的二级索引中进行匹配查找。但是在二级索引中只能查找到 Arm 对应的主键值 10。
- 由于查询返回的数据是*,所以此时,还需要根据主键值10,到聚集索引中查找10对应的记录,最终找到10对应的行row。
- 最终拿到这一行的数据,直接返回即可。
通过上述的解析,相信对回表查询已经有了一定的认识,那现在我们总结一下:
回表查询: 这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。