前言
这里主要是 探究一下 explain $sql 中各个 type
诸如 const, ref, range, index, all 的查询的影响, 以及一个初步的效率的判断
这里会调试源码来看一下 各个类型的查询 需要 lookUp 的记录
以及 相关的差异
测试表结构信息如下
CREATE TABLE `tz_test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`field1` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3333343 DEFAULT CHARSET=utf8
测试数据为序列 1 – 99
const 查询存在的记录
这里以主键查询来调试一下 这里的整个流程
select * from tz_test where id = 33;
这里是主键查询, 首先根据index获取所属分页, 然后在目标分页进行 pageDirectory 的二分查找
然后再根据用户记录 线性查找, 找到目标记录, 将 cursor 存储与 prebuilt->pcur->btr_cur->page_cur->rec
然后 后续的迭代是基于这个 记录开始迭代的
我们来看一下 ‘field33’ 记录附近的内存信息的一个剖析
下面的tuple->fields->data 记录的是比较的条件
row_search_mvcc 流程中 ”where id = 33” 条件的比较判断
比较的流程如下, 按照字段逐个比较
如果有一项比较出结果, 直接返回, 如果 所有的字段均匹配上响应 0
int 以及 一部分类型的比较方式如下, int 的比较如下 逐字节比较
其次使用 memcmp 比较两个字节序列
将 rec 复制到 mysql_rec[外部传入的 READ_RECORD 的 buf]
rec 和 mysql_rec 的相关
然后 记录往后迭代, 迭代到 field34 对应的记录
然后下一次迭代, 继续进入这里的比较, 两者不相等, row_search_mvcc 执行结束
将结果输出给客户端的地方如下
当前查询是一个 const 查询计划, 只会返回 0条 或者 1条 记录
因此, 这里就直接 退出查询了, 没有查询记录的迭代
const 查询不存在的记录
在 optimize 的时候, 发现没有匹配到的记录, 这里 打上了一个标记
初始化的时候 const_table_map 初始化为 1
join_read_const_table 是根据主键条件去查询记录, 结果没有查询到 返回状态 -1
然后 这里 found_const_table_map 一直是 0, 和后面匹配不上
根据 index 去获取 page, 根据 pageDirectory, record 去比较之后找到的最近的记录
然后 这里根据 ”where id = 33333” 比较失败, 返回 DB_RECORD_NOT_FOUND
然后 外层对异常进行处理, 最终 join_read_const_table 拿到的状态为 -1
最终 const_table_map 和 found_const_table_map 匹配不上, 进而标记了 zero_result_cause
然后 外层执行查询的时候, 发现有 zero_result_cause, 直接仅仅响应了元数据回去
完