Logo
左右连接

左右连接 #

原理 #

DBPlusEngine 目前支持绑定表、广播表和单表的左右连接查询,在进行绑定表左右连接查询时,需要在连接条件中指定分片键。分片表和广播表,分片表和单表的连接查询暂不支持,需要依赖 SQL Federation 引擎提供查询能力。

关系表如下所示:

组合关联条件是否支持处理引擎
分片表+分片表分片键+绑定内核
分片键+非绑定实验性 SQL Federation 引擎,需要手动开启
非分片键实验性 SQL Federation 引擎,需要手动开启
分片表+单表分片键实验性 SQL Federation 引擎,需要手动开启
非分片键实验性 SQL Federation 引擎,需要手动开启
分片+广播表分片键内核(存在 bug,左右连接数据重复,支持内连接)
非分片键内核(存在 bug,左右连接数据重复,支持内连接)
单表+广播表不限制内核
单表+单表不限制内核(同库场景)
不限制实验性 SQL Federation 引擎,需要手动开启(跨库场景)

DBPlusEngine 在执行绑定表的连接查询时,会选择指定了分片条件的表作为主表进行路由改写,其他绑定表根据绑定关系进行改写,然后将改写后的真实 SQL 下推到数据库执行,由于绑定表具有相同的数据分布,并且在查询时指定了分片键作为关联条件,因此原生数据库的关联查询结果可以作为逻辑 SQL 的查询结果,最后通过归并引擎对多个分片的结果进行合并。

而在执行广播表和单表的连接查询时,DBPlusEngine 会以单表为主表进行路由,然后将 SQL 下推到数据库执行,得到关联查询的结果。

建议 #

  1. 将多个具有相同分片规则的表配置为绑定表,以保证可以将关联查询下推至数据库执行。

示例 #

如下示例展示了 DBPlusEngine 支持的关联查询,t_order 和 t_order_item 为绑定表,t_config 为广播表,t_single 为单表。

-- 查询各个表的数据
mysql> select * from t_order;
+----------+---------+---------+
| order_id | user_id | content |
+----------+---------+---------+
| 2 | 2 | TEST2 |
| 4 | 1 | test11 |
| 1 | 1 | %TEST1 |
| 3 | 3 | test3 |
| 5 | 1 | test11 |
+----------+---------+---------+
5 rows in set (0.01 sec)

mysql> select * from t_order_item;
+---------+----------+---------+---------+
| item_id | order_id | content | user_id |
+---------+----------+---------+---------+
| 2 | 2 | TEST2 | 2 |
| 1 | 1 | TEST1 | 1 |
+---------+----------+---------+---------+
2 rows in set (0.01 sec)

mysql> SELECT * FROM t_config;
+-----------+---------+
| config_id | content |
+-----------+---------+
|         1 | TEST1   |
|         2 | TEST2   |
|         3 | TEST3   |
|         4 | TEST4   |
+-----------+---------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM t_single;
+-----------+---------+
| single_id | content |
+-----------+---------+
|         1 | TEST1   |
|         2 | TEST2   |
+-----------+---------+
2 rows in set (0.01 sec)

-- 绑定表左连接
mysql> select * from t_order o left join t_order_item i on o.order_id = i.order_id and o.user_id = i.user_id;
+----------+---------+---------+---------+----------+---------+---------+
| order_id | user_id | content | item_id | order_id | content | user_id |
+----------+---------+---------+---------+----------+---------+---------+
| 2 | 2 | TEST2 | 2 | 2 | TEST2 | 2 |
| 4 | 1 | test11 | NULL | NULL | NULL | NULL |
| 1 | 1 | %TEST1 | 1 | 1 | TEST1 | 1 |
| 3 | 3 | test3 | NULL | NULL | NULL | NULL |
| 5 | 1 | test11 | NULL | NULL | NULL | NULL |
+----------+---------+---------+---------+----------+---------+---------+
5 rows in set (0.01 sec)

-- 绑定表右连接
mysql> select * from t_order o right join t_order_item i on o.order_id = i.order_id and o.user_id = i.user_id;
+----------+---------+---------+---------+----------+---------+---------+
| order_id | user_id | content | item_id | order_id | content | user_id |
+----------+---------+---------+---------+----------+---------+---------+
|        2 |       2 | TEST2   |       2 |        2 | TEST2   |       2 |
|        1 |       1 | %TEST1  |       1 |        1 | TEST1   |       1 |
+----------+---------+---------+---------+----------+---------+---------+
2 rows in set (0.01 sec)

-- 广播表、单表左连接
mysql> SELECT * FROM t_config o LEFT JOIN t_single s ON o.config_id = s.single_id;
+-----------+---------+-----------+---------+
| config_id | content | single_id | content |
+-----------+---------+-----------+---------+
|         1 | TEST1   |         1 | TEST1   |
|         2 | TEST2   |         2 | TEST2   |
|         3 | TEST3   |      NULL | NULL    |
|         4 | TEST4   |      NULL | NULL    |
+-----------+---------+-----------+---------+
4 rows in set (0.00 sec)

-- 广播表、单表右连接
mysql> SELECT * FROM t_config o RIGHT JOIN t_single s ON o.config_id = s.single_id;
+-----------+---------+-----------+---------+
| config_id | content | single_id | content |
+-----------+---------+-----------+---------+
|         1 | TEST1   |         1 | TEST1   |
|         2 | TEST2   |         2 | TEST2   |
+-----------+---------+-----------+---------+
2 rows in set (0.00 sec)