Join下推
author:chenjunwen
qq:294712221
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
单表与单表
只涉及单表与单表之间的join,只要它们的存储节点相同,就可以下推
任意表与全局表
涉及任意表与全局表之间的left/inner join都可以下推
相同数据分布关系(ER关系)
涉及分片表之间的分片算法的数据分布相同同时使用拆分键进行等值查询就可以下推
分片算法的数据分布相同即除了字段信息外,其他分片算法配置相同
值得注意的是,上述说的表并非指
a join b on a.id = b.id
中a与b只能是逻辑表,而是可以使用多次运算得出的临时表
FULL JOIN都不支持下推.Mysql没有这个运算,不讨论FULL JOIN
所有
是指
INNER,LEFT,RIGHT,SEMI,ANTI
基于表类型的下推规则
左表 | 右表 | JOIN类型 | 必要下推条件 |
单表 | 单表 | 所有 | targetName相同 |
单表 | 全局表 | 所有 | |
单表 | 分片表 | 同全局表与分片表,即INNER,RIGHT | targetName相同 |
全局表 | 单表 | 所有 | |
全局表 | 分片表 | INNER,RIGHT | push_down_join_broadcast可以强制下推 |
全局表 | 全局表 | 所有 | |
分片表 | 全局表 | INNER,LEFT,SEMI,ANTI(不支持RIGHT) | push_down_join_broadcast可以强制下推 |
分片表 | 单表 | 同分片表与全局表,所有 | targetName相同 |
分片表 | 分片表 | 所有 | ER关系而且分片键等值查询 |
单表与分片表/分片表与分片表 在targetName相同的时候,单表升级为全局表(v1.21实现,此前不能)
基于分区键与分片表的下推规则(1.21-2021-11-6)
(v1.21实现,此前不能)
分区键是能对应一个分区的字段
分片键是对数据进行分区的字段,它对应一个或者多个分区
当拆分键,分片键只有一个的时候,它就是分区键
当拆分键有多个的时候,根据情况而定,比如分库键就不是分区键
分片算法中的映射算法
分片算法描述了数据如何映射到数据库实例与分区的算法
其中用targetName代表数据库实例,所以targetName是相同的时候,它们的数据就在相同的数据库实例上.
当join中带有分区键的等值查询的时候,而且左表是分片表,而且该分区键带有等值查询,命中一个分区(点查),
此时左表与右表都分别命中一个分区,则触发基于分区键的分片表下推规则
该规则不区分左右表
分片表 | 全局表 | 所有 | |
分片表 | 单表 | 所有 | targetname相同, 左侧分片表是单实例分表(单库分表) (实质上是单表升级为全局表) |
分片表 | 分片表 | 所有 | 右侧分片表是多实例单表(分库) 两表分片算法中的targetName映射算法相同 但允许表名映射算法不同 两表targetName集合相同 (由分片算法决定,内置自动hash型实现) |
两表分片算法中的targetName映射算法相同
但允许表名映射算法不同
在自动hash型算法的语境下
比如算命相同,分库数量相同,分表数量不相同,右表的分表数量是1,这个就满足
两表分片算法中的targetName映射算法相同
两表targetName集合相同
但是它们表名映射算法不同
但是要求右侧分片表是多实例单表(分库),所以右表的分表数量只能是1
实际上ER表也属于两表分片算法中的targetName映射算法相同
更为广泛的分片表规则,此规则一般使用 基于位置的下推规则 实现
左表右表都进行基于分区键的点查,都分别命中一个分区
分片表 | 分片表 | 所有 | targetname相同 两表分片算法中的targetName映射算法相同 两表targetName集合相同 (由分片算法决定,内置自动hash型实现) 使用参数动态计算出对应的左右分区并进行join |
基于位置的下推规则
(v1.20开始实现逐渐完善,v1.21完善整个规则)
在SQL带有完整参数(相对于参数化)的时候,如果计算得出左表与右表分别只有一个分区,而这两个分区的targetName是相同的,则把SQL中的左表与右表的逻辑库逻辑表名替换为对应的物理库物理表名.
此规则支持所有join类型
此规则是 基于分区键与分片表的下推规则 的扩展, 基于位置的下推规则 不支持参数化,而前者支持.
左表右表都进行基于分区键的点查,都分别命中一个分区
该规则不区分左右表
分片表 | 全局表 | 所有 | |
分片表 | 单表 | 所有 | targetname相同 左侧分片表无要求 |
分片表 | 分片表 | 所有 | targetname相同 左右侧分片表无算法要求 左右两表谓词命中一个分区 |
注意
左表右表会被join reorder,进行交换左右位置,一般交换的join类型是inner join,此时实际上不区分左右表
以上规则适用于能被重写为全局索引表的分片表
以上规则适用于能被重写为join的子查询,无法下推的join运算,mycat会进行运算得出正确的结果
若有收获,就点个赞吧