暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

条件不互斥,OR条件能否转化UNION ALL?智能SQL优化工具PawSQL给你意想不到的惊喜!

PawSQL 2025-03-24
13

概述

在SQL查询优化中,OR条件重写为UNION是一种常见的优化手段。当OR连接的两个条件互斥时,我们可以更进一步,将OR条件重写为UNION ALL,从而避免对UNION的两个部分进行去重操作,进一步提升SQL查询性能。但是如果条件不互斥,OR条件能否转化UNION ALL?PawSQL的答案是:可以。

优化场景:LIMIT + ORDER BY

在PawSQL的最新版本中,新增了一种可以将OR重写为UNION ALL的场景:当查询中存在LIMITORDER BY子句时,可以使用UNION ALL代替UNION。这一优化特别适用于需要排序并限制返回行数的查询。

示例SQL

考虑以下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优化解决方案。

        获取更多信息,欢迎关注公众号👇👇👇

        文章转载自PawSQL,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论