首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

数据库中间件 MyCAT 源码分析——跨库两表Join

摘要: 原创出处 http://www.iocoder.cn/MyCAT/two-table-share-join/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 MyCAT 1.6.5 正式版

1. 概述

2. 主流程

\3. ShareJoin

3.1 JoinParser

3.2 ShareJoin.processSQL(...)

3.3 BatchSQLJob

3.4 ShareDBJoinHandler

3.5 ShareRowOutPutDataHandler

4. 彩蛋

1. 概述

MyCAT 支持跨库表 Join,目前版本仅支持跨库表 Join。虽然如此,已经能够满足我们大部分的业务场景。况且,Join 过多的表可能带来的性能问题也是很麻烦的。

本文主要分享:

整体流程、调用顺序图

核心代码的分析

前置阅读:《MyCAT 源码分析 —— 【单库单表】查询》。

OK,Let's Go。

2. 主流程

当执行跨库两表 Join SQL 时,经历的大体流程如下:

SQL 上,需要添加注解 。 解析注解 后,路由给 作进一步处理。

获取注解对应的 实现类, 就是其中一种实现(目前也只有这一种实现),提供了跨库两表 Join 的功能。从类命名上看, 很大可能性后续会提供完整的跨库多表的 Join 功能。

核心代码如下:

3. ShareJoin

目前支持跨库表 Join。 将 SQL 拆分成左表 SQL 和 右表 SQL,发送给各数据节点执行,汇总数据结果进行合后返回。

伪代码如下:

实际情况会更加复杂,我们接下来一点点往下看。

3.1 JoinParser

负责对 SQL 进行解析。整体流程如下:

举个例子, 解析后, 结果如下:

tName :表名

tAlia :表自定义命名

where :过滤条件

order :排序条件

parenTable :左连接的 Join 的表名。 表 在 属性 的 为 "o",即 。

joinParentkey :左连接的 Join 字段

joinKey :join 字段。 表 在 属性 为 。

join :子 tableFilter。即,该表连接的右边的表。

parent :和 属性 相对。

看到此处,大家可能有疑问,为什么要把 SQL 解析成 。 根据 生成数据节点执行 SQL。代码如下:

当 为空时,即on/where 等于号左边的表。例如: 。

当 不为空时,即on/where 等于号右边的表。例如: 。

3.2 ShareJoin.processSQL(...)

当 SQL 解析完后,生成左边的表执行的 SQL,发送给对应的数据节点查询数据。大体流程如下:

当 SQL 为 时, 的返回结果为 。

生成左边的表执行的 SQL 后,顺序顺序顺序发送给对应的数据节点查询数据。具体顺序查询是怎么实现的,我们来看下章BatchSQLJob

3.3 BatchSQLJob

对 封装,提供上层两个方法:

executeNativeSQLSequnceJob :顺序(非并发)在每个数据节点执行SQL任务

executeNativeSQLParallJob :并发在每个数据节点执行SQL任务

核心代码如下:

通过执行中任务列表待执行任务列表来实现顺序/并发执行任务。核心代码如下:

顺序执行时,当 存在执行中的任务时, 时,不立即执行,添加到 。当 完成时,顺序调用下一个任务。

并发执行时, 时,立即执行。

SQL 异步执行任务。其 属性,在 SQL 执行有返回结果时,会进行回调,从而实现异步执行。

在 里, 有两个实现: 、 。前者,左边的表执行的 SQL 回调;后者,右边的表执行的 SQL 回调。

3.4 ShareDBJoinHandler

左边的表执行的 SQL 回调。流程如下:

:接收数据节点返回的 fields,放入内存。

:接收数据节点返回的 row,放入内存。

:接收完一个数据节点返回所有的 row。当所有数据节点都完成 SQL 执行时,提交右边的表执行的 SQL 任务,并行执行,即图中#createQryJob(...)

当 SQL 为 时, 的返回结果为 。

核心代码如下:

3.5 ShareRowOutPutDataHandler

右边的表执行的 SQL 回调。流程如下:

:接收数据节点返回的 fields,返回 header 给 MySQL Client。

:接收数据节点返回的 row,匹配左表的记录,返回合并后返回的 row 给 MySQL Client。

:当所有 row 都返回完后,返回 eof 给 MySQL Client。

关注公众号

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180919B08TCU00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券