【MySQL·8.0·源码】MySQL 表的扫描方式

前言

在进一步介绍 MySQL 优化器时,先来了解一下 MySQL 单表都有哪些扫描方式。
单表扫描方法是基表的读取基础,也是完成表连接的基础,熟悉了基表的基本扫描方式,
即可以倒推理解 MySQL 优化器层的诸多考量。

基表,即数据库中的原始表,与之对应的是视图、物化临时表或其他形式的派生表(中间生成的)
基表是直接存储实际数据的,在查询语法树中,一般叶子节点所对应的表为基表,
MySQL 语法树大致结构可以参考【MySQL·8.0·源码】MySQL 语法树结构

MySQL 支持不同的存储引擎,以 InnoDB 举例,InnoDB 存储引擎采用的是
一种 Index-organized(clustered index)的方式来组织数据。
InnoDB 数据存储的一些关键特点:

  • InnoDB 内部数据分割成固定大小的数据页(16KB)
  • 每个数据页中存储有序的数据行,且按照主键(即聚簇索引)顺序存储,主键本身也是一颗 B+ 树
  • 非主键索引即二级索引叶子节点存储主键值,而非实际数据行,想通过二级索引定位到实际行要通过主键跳转

对物理结构感兴趣的可以去看 innodb_ruby 工程
innodb_diagrams

AccessMethods

对基表的读取方式,数据库中有专门的术语,称为 access method
想要读取一张表的记录,无非两种方式:

  • 直接从表存储的页上进行扫描,即直接做表扫描
  • 通过索引检索记录数据

直接表扫描比较简单,因为记录行已经是按某种顺序存储在数据页上的,直接扫描 data page
索引扫描,根据索引不同(clustered key、second index key),可以衍生出多种扫描方式

TABLE_SCAN

在 TABLE_SCAN 中,所有非空的数据页都会被扫描一次,无论被扫描的数据页是否包含所期望的记录,
但仅只会被扫描一次,然后可以对扫描的记录进行谓词比较,即可返回正确所期望的结果

INDEX_SCAN

不同类型索引的不同处理

  • clustered index
    由于 clustered index 的特性:
    即 tuple 是按着 clustered index 的顺序插入到 data page 中的,所以 clustered index 的键值顺序和 data page 中的 tuple
    的物理顺序是一致的,所以扫描 clustered index 也意味着扫描了一次 table data page。

  • second index
    普通的二级索引不一样,由于二级索引上的键值顺序是以二级索引列为准,而非 tuple 实际的物理顺序,所以
    如果 data 同一个 page 上两个 tuple 在二级索引列上不是紧挨着的顺序,则在扫描二级索引时,该 data page 可能
    会被多次扫描到。

同 TABLE_SCAN 要完整的扫描一次所有的非空 data page 不同,INDEX_SCAN 一般无需扫描整个表,可以
通过指定索引的起始键值和终止键值,仅扫描索引值范围内的记录即可。

MySQL 的 Access Method

TABLE_SCAN

MySQL 的 TABLE_SCAN 没有特别的不同,唯一特殊的是对常量表的特别处理

  • SYSTEM
    当 MySQL 发现基表只有一行行记录时,MySQL 会专门将其访问类型标记为 system,并且会直接记录值
    并且物化处理,以显著简化 join 顺序选择
    在这里插入图片描述
  • ALL
    MySQL 将完整的 table scan 标记为 ALL,当为 ALL 时,会对所有非空的 data page 进行完整扫描一次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抡着鼠标扛大旗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值