一、Lateral 查询语法介绍
在上文Lateral 查询详解:概念、适用场景与普通 JOIN 的区别中介绍到,Lateral 查询是SQL中的一种连接方式,它允许FROM子句中的子查询引用同一FROM子句中前面的表的列。虽然这种特性提供了强大的表达能力,但在某些场景下可能导致性能问题。PawSQL优化器近日实现了一种针对特定类型Lateral Join的重写优化方案,以提升查询性能。
PawSQL优化器中的LateralQueryRewrite
类负责这一优化过程,其核心原理是:
Lateral 查询重写优化必须满足以下条件:
注1:聚合并不是解关联的必要条件,非聚合Lateral查询的解关联在查询折叠中被优化。
让我们分析一个实际案例,看看PawSQL优化器如何应用Lateral Join 重写优化的。
select *
from customer, lateral (
select SUM(o_totalprice)
from orders
where o_custkey= c_custkey
and o_orderdate='1998-03-03'
)as total
o_custkey = c_custkey
(等值谓词)select/*QB_1*/*from customer,(
select/*QB_2*/SUM(o_totalprice), o_custkey
from orders
where o_orderdate='1998-03-03'
group by o_custkey
)as total
where total.o_custkey= c_custkey
customer
表的列,变成了独立子查询o_custkey
GROUP BY o_custkey
子句o_custkey = c_custkey
被移到了外层的WHERE子句o_orderdate = '1998-03-03'
保留在内部查询中根据执行计划比较,这一重写带来了显著的性能提升(约2172.57%)。
优化前
Nested Loop (cost=8.44..127635.00 rows=15000 width=223) (actual time=0.054..36.043 rows=15000 loops=1)
-> Seq Scan on customer (cost=0.00..510.00 rows=15000 width=191) (actual time=0.012..1.640 rows=15000 loops=1)
-> Aggregate (cost=8.44..8.45 rows=1 width=32) (actual time=0.002..0.002 rows=1 loops=15000)
-> Index Scan using ord_idx3 on orders (cost=0.42..8.44 rows=1 width=8) (actual time=0.002..0.002 rows=0 loops=15000)
Index Cond: ((o_custkey = customer.c_custkey) AND (o_orderdate = '1998-03-03'::date))
Planning Time: 2.984 ms
Execution Time: 36.597 ms
优化后
Nested Loop (cost=0.71..441.97 rows=62 width=227) (actual time=0.367..1.586 rows=59 loops=1)
-> GroupAggregate (cost=0.42..6.59 rows=62 width=36) (actual time=0.068..0.136 rows=59 loops=1)
Group Key: orders.o_custkey
-> Index Only Scan using pawsql_idx1255915527 on orders (cost=0.42..5.50 rows=62 width=12) (actual time=0.061..0.074 rows=59 loops=1)
Index Cond: (o_orderdate = '1998-03-03'::date)
Heap Fetches: 0
-> Index Scan using customer_pkey on customer (cost=0.29..7.01 rows=1 width=191) (actual time=0.024..0.024 rows=1 loops=59)
Index Cond: (c_custkey = orders.o_custkey)
Planning Time: 0.656 ms
Execution Time: 1.623 ms
PAWSQL_IDX1255915527,且结果集只返回59行结果
PawSQL优化器的Lateral Join 重写优化通过将相关Lateral查询转换为非相关子查询,有效地改变了查询的执行策略,大幅提高了性能。这一优化特别适用于包含聚合操作的Lateral 查询,通过重写可以减少冗余计算,更好地利用索引,并允许数据库引擎选择更优的执行计划。
在设计复杂查询时,了解这种优化机制可以帮助开发人员编写更加高效的SQL语句。同时,对于已有的使用Lateral 的查询,可以考虑使用类似PawSQL的优化工具来提升性能。