从Join的实现窥探MySQL迭代器

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

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

以下初始化数据:

1DROPTABLE IF EXISTS `t1`;
2CREATETABLE `t1` (
3 `a` int DEFAULT NULL,
4 `b` varchar(20) DEFAULT NULL
5)
6INSERTINTO `t1` VALUES(1,'a');
7INSERTINTO `t1` VALUES(1,'b');
8INSERTINTO `t1` VALUES(4,'a');
9INSERTINTO `t1` VALUES(5,'a');
10
11DROPTABLE IF EXISTS `t2`;
12CREATETABLE `t2` (
13 `c` int DEFAULT NULL,
14 `d` varchar(20) DEFAULT NULL
15)
16INSERTINTO `t2` VALUES(9,'i');
17INSERTINTO `t2` VALUES(1,'i');
18INSERTINTO `t2` VALUES(2,'i');
19INSERTINTO `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内定义的tr1和tr2。

函数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内首先会对当前的执行优化操作。

调用查询表达式Query_expression​的优化器unit->optimize​,此函数中会对该Query_expression​的内的每个查询块query_block分别先进行优化操作。

查询块内函数bool JOIN::optimize()​内会将每个查询块优化生成查询执行计划 ,具体执行函数为函数JOIN::create_access_paths()内create_root_access_path_for_join()​函数,以当前查询为例在函数create_root_access_path_for_join​内根据参数条件主要调用ConnectJoins函数。

在函数ConnectJoins​内调用FindSubstructure判断是join类型内连接、外连接、半链接等类型。

根据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)。

函数Query_expression::ExecuteIteratorQuery​内主要执行m_root_iterator->Init()​,迭代器iterator初始化,当前范例为使用HashJoinIterator​类型迭代器,因此对应执行迭代器函数HashJoinIterator::Init()。

执行m_build_input->Init()​来初始右表table句柄,用于下面函数BuildHashTable()​内读取右表数据以便初始化返回数据存储表hashtable​,值得注意的是BuildHashTable​函数内会根据处理流程调用SetReadingProbeRowState设置执行状态用于引导后续迭代器iterator执行流程。

函数内最后调用InitProbeIterator​执行m_probe_input->Init()初始左表table句柄用于下面函数读取左表数据。

上面操作完成后执行m_root_iterator->Read()​函数,以当前查询为范例其对应int HashJoinIterator::Read()​函数,执行过程中根据前面SetReadingProbeRowState​设置的流程状态再选择对应的操作函数,以当前范例则会循环读取左表数据,而在操作函数内也会调用SetReadingProbeRowState​来设置迭代器iterator下一步操作,直至迭代器处理完成,其中在函数Query_expression::ExecuteIteratorQuery,每次读取一条成功后就会调用send_data操作将结果发送至客户端,直至所有查询结果发送完成。

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

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/237383.html<

(0)
管理的头像管理
上一篇2025-04-22 11:05
下一篇 2025-04-22 11:06

相关推荐

  • 云服务器和云虚拟主机怎么选?云服务器和虚拟主机区别

    云服务器适合业务增长快、需弹性扩展的场景,而云虚拟主机适合预算有限、技术门槛低的小型静态网站或测试环境,二者核心区别在于资源独享性与运维复杂度,核心差异解析:从底层架构到使用体验很多人容易混淆这两者,觉得它们都是“买空间建站”,它们的底层逻辑完全不同,云服务器(ECS)就像是你租了一整栋别墅,水电网络独立,你想……

    2026-06-29
    0
  • 赣州智慧旅游招聘是真的吗?赣州旅游人才招聘信息

    中级岗位(3-5年经验)月薪范围通常在6000-10000元,这类岗位需要独立负责项目模块,如独立运营一个抖音账号,或维护一个景区小程序的功能迭代,具备成功案例的候选人议价能力较强,高级岗位(5年以上经验)月薪范围通常在10000-20000元,部分核心管理岗可达更高,这类人才需要具备战略规划能力,如制定整个景……

    2026-06-29
    0
  • 赣州智能物联网车位锁如何管理?智能车位锁管理系统多少钱

    赣州智能物联网车位锁管理的核心在于通过云端平台实现远程控锁、状态实时监控及自动计费,彻底解决传统车位“被占难管”与“找位难”的痛点,在赣州这样的城市,随着机动车保有量的持续增长,老旧小区、商业综合体以及私人固定车位的资源矛盾日益凸显,传统的机械地锁或简易遥控锁,不仅操作繁琐,更无法实现数据化管理,引入智能物联网……

    2026-06-29
    0
  • 赣州智能消防栓好用吗,智能消防栓多少钱一个

    赣州智能消防栓通过物联网技术实现实时监测与远程报警,能显著降低火灾响应时间并提升城市消防安全管理水平,是目前智慧城市建设中不可或缺的基础设施,赣州智能消防栓的核心价值与应用场景传统消防栓往往存在“看不见、摸不着、用不了”的痛点,在赣州这样地形复杂、老城区与新城区并存的区域,传统设施的管理难度极大,智能消防栓的出……

    2026-06-29
    0
  • 云服务器和物理机到底有啥区别?

    云服务器本质上是虚拟化资源池中的弹性实例,而传统物理服务器是独占的硬件实体,前者胜在弹性与运维便捷,后者强在物理隔离与性能稳定,具体选择取决于业务对成本、扩展性及安全合规的权衡,很多人初次接触服务器时,容易把“云服务器”和“传统物理服务器”混为一谈,觉得它们都是用来跑网站或存数据的盒子,这两者的底层逻辑完全不同……

    2026-06-29
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注