概述
在SQL查询优化中,OR条件重写为UNION是一种常见的优化手段。当OR连接的两个条件互斥时,我们可以更进一步,将OR条件重写为UNION ALL,从而避免对UNION的两个部分进行去重操作,进一步提升SQL查询性能。但是如果条件不互斥,OR条件能否转化UNION ALL?PawSQL的答案是:可以。
在PawSQL的最新版本中,新增了一种可以将OR重写为UNION ALL的场景:当查询中存在LIMIT和ORDER BY子句时,可以使用UNION ALL代替UNION。这一优化特别适用于需要排序并限制返回行数的查询。
考虑以下SQL查询:
select
l_orderkey,
l_extendedprice,
l_discount
from
lineitem
where
L_PARTKEY = 100
or L_SUPPKEY = 100
order by
l_extendedprice desc
在PawSQL 2025.03.11版本之前,PawSQL会将其重写为:
select
PawDT_1742549815973.l_orderkey,
PawDT_1742549815973.l_extendedprice,
PawDT_1742549815973.l_discount
from
(
(select /*QB_1*/
l_orderkey,
l_extendedprice,
l_discount,
l_linenumber
from
lineitem
where
L_SUPPKEY = 100
order by
l_extendedprice desc
limit 10)
union
(select /*QB_2*/
l_orderkey,
l_extendedprice,
l_discount,
l_linenumber
from
lineitem
where
L_PARTKEY = 100
order by
l_extendedprice desc
limit 10)
) as PawDT_1742549815973
order by
PawDT_1742549815973.l_extendedprice desc
limit 10
在这个版本中,执行计划显示在UNION操作时需要进行去重操作(Union materialize with deduplication
),这会增加额外的计算开销。
最新优化:UNION ALL
在最新的PawSQL版本中,查询被重写为:
select
PawDT_1742549815973.l_orderkey,
PawDT_1742549815973.l_extendedprice,
PawDT_1742549815973.l_discount
from
(
(select /*QB_1*/
l_orderkey,
l_extendedprice,
l_discount,
l_linenumber
from
lineitem
where
L_SUPPKEY = 100
order by
l_extendedprice desc
limit 10)
union all
(select /*QB_2*/
l_orderkey,
l_extendedprice,
l_discount,
l_linenumber
from
lineitem
where
L_PARTKEY = 100
order by
l_extendedprice desc
limit 10)
) as PawDT_1742549815973
order by
PawDT_1742549815973.l_extendedprice desc
limit 10
在这个版本中PawSQL使用UNION ALL代替了UNION,执行计划显示UNION操作不再需要去重(Union materialize
),从而减少了不必要的计算,进一步提升了查询性能,执行时间从6.187ms进一步降低到0.464ms,性能进一步提升了10倍!
总结
PawSQL在特定场景下(如条件互斥或是存在LIMIT和ORDER BY子句时),通过将OR条件重写为UNION ALL,能够显著提升SQL查询的性能。
关于PawSQL
PawSQL专注于数据库性能优化自动化和智能化,提供的解决方案覆盖SQL开发、测试、运维的整个流程,广泛支持多种主流商用和开源数据库,为开发者和企业提供一站式的创新SQL优化解决方案。