21 mysql ref 查询

前言

这里主要是 探究一下 explain $sql 中各个 type

诸如 const, ref, range, index, all 的查询的影响, 以及一个初步的效率的判断

这里会调试源码来看一下 各个类型的查询 需要 lookUp 的记录

以及 相关的差异

此系列文章建议从 mysql const 查询 开始看

测试表结构信息如下

复制代码
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

r e f 查询存在的记录

更新表结构, 增加 field1 的索引配置

复制代码
CREATE TABLE `tz_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `field1` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `field1` (`field1`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3333343 DEFAULT CHARSET=utf8

执行更新, 更新一部分记录的 field1 为 "field33"

update tz_test set field1 = 'field33' where id in (33, 35, 60);

mysql 读取索引, 这个是在读取索引的数据, 然后和 查询条件进行对比

索引记录存放了 原字段的值 -> 记录的主键

这里获取到第一个匹配的索引记录

up_rec 索引记录信息如下, 为 'field33' -> 33

然后这里将 pcur->btr_cur->page_cur.rec 更新为 'field33' -> 33 对应的索引的位置

然后 接下来就是 读取索引的记录

然后是比较 索引字段的信息 和 查询条件, 如果匹配上 才获取对应的记录

是否需要 查询真实记录 ?

这里会有两种情况, 一种情况是查询的 索引字段 以及 主键, 不需要额外的查询真实记录, 术语称之为 覆盖索引

假设是普通字段, 这里更新 need_to_access_clustered 为 TRUE

另外一种是需要根据 主键关联查询 到 真实的记录, 术语称之为 回表

修改数据表结构如下

复制代码
CREATE TABLE `tz_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `field1` varchar(12) DEFAULT NULL,
  `field2` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `field1` (`field1`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8

update tz_test set field2 = id;

row_sel_get_clust_rec_for_mysql 中是根据索引记录获取真实的记录

prebuilt->clust_ref 为根据索引记录构造出的 主键查询条件

btr_pcur_open_with_no_init 根据这个主键查询条件去定位目标记录, 将记录信息更新到 prebuilt->cluster_pcur 中相关

根据索引记录 构造 主键查询条件的地方, 比如这里 'field33' -> 35 的索引记录

构造出来的主键查询条件为 "where id = 35"

更新待复制 rec 为 cluster_rec, 这里的 cluter_rec 为真实记录的地址信息

cluster_rec 的记录信息如下

读取到了真实记录的信息到 mysql_buf

然后不断向下迭代索引记录, 这里是迭代到了 'field33' -> 35

依次会迭代 'field33 -> 60', 'field34' -> 34

到 'field34' -> 34 的时候, 比较索引条件 跳出了 row_search_mvcc 的循环

这里遍历的索引记录信息依次如下, 索引是按照顺序排列的

到 'field34' -> 34 的时候, 比较索引条件 跳出了 row_search_mvcc 的循环

第二条以及之后的记录是缓存在了 prebuilt->fetch_cache 中, 最多预取 7 条记录

第二次, 第三次获取数据是直接通过缓存获取

这里 prebuilt->fetch_cache 中各个元素是已经转换好了的 mysql_rec, 因此 这里是直接 memcpy 到 READ_RECORD.record 中即可

ref 查询不存在的记录

比如说我这里执行一个查询 "select * from tz_test where field1 = 'field133';"

然后时 查询不到记录的, 这里来调试一下 这里的整个流程

查询索引, 定位到的最近的一条记录是索引记录 'field14 -> 14', 然后是根据是根据条件进行匹配, 结果匹配不上退出 row_search_mvcc

索引条件匹配不上之后退出

然后外层迭代 记录/索引 这一层处理, 跳出循环

最终响应 0 条记录

相关推荐
一个天蝎座 白勺 程序猿4 分钟前
KingbaseES在政务领域的应用实践——武汉人社大数据平台“数字化服务新模式”
大数据·数据库·政务·kingbasees·金仓数据库
一起养小猫6 分钟前
《Java数据结构与算法》第三篇(下)队列全解析:从基础概念到高级应用
java·开发语言·数据结构
vx_vxbs6614 分钟前
【SSM电动车智能充电服务平台】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·mysql·spring cloud·小程序·php·idea
叹隙中驹石中火梦中身18 分钟前
解耦神器Event和EventListener
java
Boop_wu27 分钟前
[Java EE] 多线程进阶(JUC)(2)
java·jvm·算法
小坏讲微服务28 分钟前
SpringCloud整合Scala实现MybatisPlus实现业务增删改查
java·spring·spring cloud·scala·mybatis plus
N***p36530 分钟前
五大消息模型介绍(RabbitMQ 详细注释版)
java·rabbitmq·java-rabbitmq
雨中飘荡的记忆1 小时前
深入理解设计模式之单例模式
java·设计模式
程序员西西1 小时前
Spring Boot整合MyBatis调用存储过程?
java·后端
f***01931 小时前
【MySQL】JDBC的连接
数据库·mysql