文档

LEFT JOIN(左连接)消除

更新时间:

PolarDB支持LEFT JOIN(左连接)消除功能。对于满足前提条件的复杂查询,通过该功能可以对SQL查询进行变换,即去掉不必要的LEFT JOIN子查询,从而提升SQL查询的性能。

前提条件

集群版本需为PolarDB MySQL版8.0版本且修订版本需满足如下条件:

  • 8.0.1.1.32或以上。

  • 8.0.2.2.10或以上。

如何查看集群版本,请参见查询版本号

使用限制

使用LEFT JOIN(左连接)消除功能,需要同时满足以下条件:

  • 对于左表中的任意一行数据,右表中能匹配JOIN条件的行数有且仅有一行。

  • LEFT JOIN子查询以外,当前SQL语句中的其他地方没有引用右表的数据。

背景信息

LEFT JOIN(左连接)在复杂分析查询中被广泛使用,是所有SQL查询中最常见和最耗时的算子。一个连接操作,需要将左右两边的关系(表)根据连接条件中指定的连接列,拼接到一起与主查询进行关联,极大的提升了查询的复杂度。如果可以消除掉不必要的连接操作,将对查询的性能有很大的提升。

使用方法

您可以通过loose_join_elimination_mode参数开启LEFT JOIN(左连接)消除功能。具体操作请参见设置集群参数和节点参数

参数名称

级别

描述

loose_join_elimination_mode

Global

LEFT JOIN(左连接)消除功能控制开关。取值范围:

  • REPLICA_ON(默认值):仅在只读节点开启LEFT JOIN(左连接)消除功能。

  • ON:开启LEFT JOIN(左连接)消除功能。

  • OFF:关闭LEFT JOIN(左连接)消除功能。

示例

原查询

原始查询基于table1table2table3LEFT JOIN得到最终的记录条数,该查询的执行时间为7.5秒。

EXPLAIN
SELECT count(*)
FROM `table1` `sc`
  LEFT JOIN `table2` `ca` ON `sc`.`car_id` = `ca`.`id`
  LEFT JOIN `table3` `co` ON `sc`.`company_id` = `co`.`id`;

+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref                   | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
|  1 | SIMPLE      | sc    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL                  |    2 |   100.00 | NULL        |
|  1 | SIMPLE      | ca    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | je_test.sc.car_id     |    1 |   100.00 | Using index |
|  1 | SIMPLE      | co    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | je_test.sc.company_id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+

上述查询中,table1对于table2table3的连接条件中都使用了表的主键,保证了输出的唯一性。且在投影列中没有引用table2table3的任何表列,因此LEFT JOIN可以被安全的消除。

变换后的查询

EXPLAIN
SELECT count(*)
FROM `table1` `sc`

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | sc    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+

通过上述查询可以看到,在消除table2table3后,只需要查询table1的记录。可以极大的节省计算资源,提升执行效率。该查询的执行时间是0.1秒,相比原查询提升了75倍。