从join的实现窥探MySQL迭代器

以如下left join查询语句为范例:

select * from t1 left join t2 on t1.c=t2.a ;

以下初始化数据:

1  DROP TABLE IF EXISTS t1;
2    CREATE TABLE t1 (
3      a int DEFAULT NULL,
4      b varchar(20) DEFAULT NULL
5    )
6    INSERT INTO t1 VALUES (1, 'a');
7    INSERT INTO t1 VALUES (1, 'b');
8    INSERT INTO t1 VALUES (4, 'a');
9    INSERT INTO t1 VALUES (5, 'a');
10
11    DROP TABLE IF EXISTS t2;
12    CREATE TABLE t2 (
13      c int DEFAULT NULL,
14      d varchar(20) DEFAULT NULL
15    )
16    INSERT INTO t2 VALUES (9, 'i');
17    INSERT INTO t2 VALUES (1, 'i');
18    INSERT INTO t2 VALUES (2, 'i');
19    INSERT INTO t2 VALUES (3, 'i');

1.处理join的yacc入口

sys_yacc.yy文件内解析 t1 left join t2 on t1.c=t2.a;对应处理位置

1  table_reference outer_join_type table_reference ON_SYM expr
2    {
3  $$= NEW_PTN PT_joined_table_on($1, @2, $2, $3, $5);
4    }

其中outer_join_type对应

1  outer_join_type:
2    LEFT opt_outer JOIN_SYM          { $$= JTT_LEFT; }
3  | RIGHT opt_outer JOIN_SYM         { $$= JTT_RIGHT; }

入参处理在函数 T_joined_table_on

2.移步到函数PT_joined_table_on

PT_joined_table_on声明可知其继承 PT_joined_table函数,入参左右表赋值为 PT_joined_table内定义的 tr1tr2

函数 PT_joined_table_on将输入join的左右表加入context内,并调用 add_join_on将on内的条件加入右表,记录后续数据过滤条件。

3.执行阶段函数do_command(thd)

具体对应执行函数 int mysql_execute_command(THD *thd, bool first_level),语句解析以及相应参数保存完成后,进入函数 int mysql_execute_command(THD *thd, bool first_level),此函数内根据前面解析到的命令类型 switch (lex->sql_command)调用对应的处理函数,如当前语句为例查询命令解析为 lex->sql_command = SQLCOM_SELECT则进入函数 lex->m_sql_cmd->execute(thd);其对应为 sql_select.cc内函数 bool Sql_cmd_dml::execute(THD *thd)

4.优化器操作,生成access_paths

sql_select.cc内函数 bool Sql_cmd_dml::execute(THD *thd)函数内主要操作为函数 execute_inner,在函数 execute_inner内首先会对当前的执行优化操作,

  1. 调用查询表达式 Query_expression的优化器 unit->optimize,此函数中会对该 Query_expression的内的每个查询块 query_block分别先进行优化操作,
  2. 查询块内函数 bool JOIN::optimize()内会将每个查询块优化生成查询执行计划 ,具体执行函数为函数 JOIN::create_access_paths()create_root_access_path_for_join()函数,以当前查询为例在函数 create_root_access_path_for_join内根据参数条件主要调用 ConnectJoins函数
  3. 在函数 ConnectJoins内调用 FindSubstructure判断是join类型内连接、外连接、半链接等类型
  4. 根据 FindSubstructure返回join类型调用相应的函数生成path,当前查询为例执行调用 CreateHashJoinAccessPath生成path。

至此查询块 query_block的优化操作和path生成完成,查询块优化操作完成后再执行整体表达式 Query_expression的优化和path的生成,因为目前范例仅为一个查询块,所以当前无需再做整体表达式的优化和path生成。

5.创建迭代器iterator

根据上一步生成的path调用 CreateIteratorFromAccessPath函数生成迭代器,用于循环操作各表数据。

在此函数内会根据path的类型调用生成不同类型的迭代器,以目前范例为例,会调用迭代器类型为 HashJoinIterator

6.上述4、5步执行完成后,执行迭代器iterator

在函数 execute_inner内执行完成上述4、5步骤操作后主要继续执行 unit->execute(thd)函数,其对应执行查询表达式函数 bool Query_expression::ExecuteIteratorQuery(THD *thd)

  1. 函数 Query_expression::ExecuteIteratorQuery内主要执行 m_root_iterator->Init(),迭代器iterator初始化,当前范例为使用 HashJoinIterator类型迭代器,因此对应执行迭代器函数 HashJoinIterator::Init()
  2. 执行 m_build_input->Init()来初始右表table句柄,用于下面函数 BuildHashTable()内读取右表数据以便初始化返回数据存储表 hashtable,值得注意的是 BuildHashTable函数内会根据处理流程调用 SetReadingProbeRowState设置执行状态用于引导后续迭代器iterator执行流程。
  3. 函数内最后调用 InitProbeIterator执行 m_probe_input->Init()初始左表table句柄用于下面函数读取左表数据。
  4. 上面操作完成后执行 m_root_iterator->Read()函数,以当前查询为范例其对应 int HashJoinIterator::Read()函数,执行过程中根据前面 SetReadingProbeRowState设置的流程状态再选择对应的操作函数,以当前范例则会循环读取左表数据,而在操作函数内也会调用 SetReadingProbeRowState来设置迭代器iterator下一步操作,直至迭代器处理完成,其中在函数 Query_expression::ExecuteIteratorQuery,每次读取一条成功后就会调用send_data操作将结果发送至客户端,直至所有查询结果发送完成。

7.至此客户端收到相应显示查询结果。

Enjoy GreatSQL 😃

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

欢迎来GreatSQL社区发帖提问
https://greatsql.cn/

从join的实现窥探MySQL迭代器

技术交流群:

微信:扫码添加 GreatSQL社区助手微信好友,发送验证信息 加群

从join的实现窥探MySQL迭代器

Original: https://www.cnblogs.com/greatsql/p/16696620.html
Author: GreatSQL
Title: 从join的实现窥探MySQL迭代器

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/598638/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 一致性hash算法

    背景 当我们的业务系统大到一定程度的时候,一台缓存服务器显然不能满足需求,需要使用多台缓存服务器。然后缓存服务器具体一定的用户粘性属性,如何设计缓存服务器使其命中率提高,并具有伸缩…

    数据库 2023年6月9日
    072
  • MySQL(一)——查看密码与修改

    查看数据库密码,策略与修改 RPM安装: 源码安装: 进入:数据库 进入数据库后第一步设置密码: 查看密码策略 修改密码策略,长度 0宽容模式 混合模式,0关闭大小写 特殊字符 O…

    数据库 2023年6月14日
    0112
  • 【黄啊码】PHP对接阿里云短信服务最新版(官方文档有坑,切记)

    现在百度出来的大都是1.5的版本,而阿里云短信API出到了2.0了 以下是最新教程,绝对成功,不成功。。。我再改一遍! 环境要求最低要求 PHP 5.6安装 SDK 核心库 Ope…

    数据库 2023年6月16日
    0199
  • 局域网内访问子网服务(访问电脑虚拟机中的服务)

    局域网内访问子网服务 问题描述: 同一个路由器(172.18.0.0)下面有两台电脑A(172.18.40.45)和B (172.18.44.173) ,在B电脑上安装虚拟机 ,使…

    数据库 2023年6月9日
    084
  • Mall 动态权限学习参考

    代码仓库 https://github.com/Rain-with-me/JavaStudyCode/tree/main/4-springboot-security-dynic 本…

    数据库 2023年6月14日
    072
  • jdbc-使用工具类

    package com.cqust; import com.cqust.utils.JDBCUtil; import java.sql.Connection;import java…

    数据库 2023年6月11日
    061
  • MySQL实战45讲 15

    15 | 答疑文章(一):日志和索引相关问题 日志相关 binlog(归档日志)和redo log(重做日志)配合崩溃恢复,在两阶段提交的不同瞬间,MySQL如果发生异常重启,是怎…

    数据库 2023年6月16日
    0128
  • QQ登录简介

    QQ登录简介 (1) QQ登录 QQ登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目。 若想实现QQ登录,需要成为QQ互联的…

    数据库 2023年6月14日
    064
  • [springmvc]拦截器功能

    11.拦截器 只会拦截controller的请求,对于静态资源不处理 被spring代理的拦截器实现只需要两步: 1.实现一个拦截器类 package com.spring.con…

    数据库 2023年6月16日
    073
  • mysql事物

    MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些…

    数据库 2023年6月9日
    073
  • Java中的线程安全与线程同步

    1.为什么需要线程同步 什么是线程安全:指在 被多个线程访问时,程序可以 持续进行正确的处理。 1.1.线程安全问题 案例:通过抢优惠例子说明线程安全问题 public class…

    数据库 2023年6月6日
    076
  • 代码圈复杂度

    回到我们日常的写代码的场景,我们一直在说系统很复杂,那到底什么是系统复杂度呢?最近几天,一直在改项目里别人写的代码,某些方法复杂无注释。怎么才能写的一手可读,可扩展,可维护[注1]…

    数据库 2023年6月14日
    082
  • MySQL行构造器

    子查询返回多列的办法 主要用途,项目中初版使用子查询返回一列用来限制主表,项目新版本中,表关联建改为多列时建议使用 Original: https://www.cnblogs.co…

    数据库 2023年6月9日
    069
  • maven项目编译报错处理

    1、问题一: [ERROR] Failed to execute goal on project data-common:Could not resolve dependencie…

    数据库 2023年6月11日
    085
  • 3_MyBatis

    一. 引言 1.1 什么是框架? 软件的半成品, 解决了软件开发过程中的普适性问题, 从而简化了开发步骤, 提升了开发效率 1.2 什么是ORM框架? ORM(Object Rel…

    数据库 2023年6月11日
    071
  • Redis-数据结构

    Redis key-value结构组织 首先,Redis使用了一个全局哈希表来保存所有的键值对。这个全局哈希表,也就是一个存放哈希桶(entry)的数组。Redis可以用哈希算法算…

    数据库 2023年6月11日
    071
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球