Oracle SQL WITH 语句是不是比 subselect 更好 [关闭]

Posted

技术标签:

【中文标题】Oracle SQL WITH 语句是不是比 subselect 更好 [关闭]【英文标题】:Is Oracle SQL WITH statement better than subselect [closed]Oracle SQL WITH 语句是否比 subselect 更好 [关闭] 【发布时间】:2018-03-16 14:31:48 【问题描述】:

我有一个超过 1000 行的 Oracle 查询。分解它和/或使用存储过程不是这里的选择。我打算让它更长。其中哪个性能更好?我发现 WITH 版本更易于阅读。

  /* subselect */
  select col01
        ,col02
  from (
    select case col01 when 'X' then 1 else 2 end col01
          ,case col02 when 'Y' then 3 else 4 end col02
    from (      
      select upper(col01) col01
            ,upper(col02) col02
      from (      
        select 'x' as col01
              ,'y' as col02
        from dual
      )
    )
  )
  ;
  ---------------------------------------
  /* with statement */
  with qry01 as (
  select 'x' as col01
        ,'y' as col02
  from dual
  )
  ,qry02 as (
  select upper(col01) col01
        ,upper(col02) col02
  from qry01      
  )
  ,qry03 as (
  select case col01 when 'X' then 1 else 2 end col01
        ,case col02 when 'Y' then 3 else 4 end col02
  from qry02      
  )
  select col01
        ,col02
  from qry03      
  ;

【问题讨论】:

性能应该基本相同。 Oracle 优化器确定最佳查询计划。使用 CTE(允许实现)可能会稍微灵活一些,但如果 CTE 只被引用一次,这无关紧要。 您无法通过查看或在互联网上询问来确定查询性能;唯一确定的方法是测试。我想这些也不是您的实际查询。 谢谢@mustaccio。这个简化的版本,很好地简化了。在花费数小时将其从一个转换为另一个之前,我只是在寻找建议。 【参考方案1】:

我还发现 CTE WITH 表达式更易于阅读。除此之外,还有理由更喜欢它。

您可以在主查询中多次使用 CTE 子查询。 Oracle 优化器可以将 CTE 子查询的结果存储在动态创建的临时表中。 (注意,你甚至可以通过无证提示/*+ MATERIALIZE */强制它) 您可以递归使用 CTE,请参阅Recursive Subquery Factoring

【讨论】:

我相信第二点也适用于非 CTE 子查询。 @trincot,我不知道,似乎不太清楚:Materialize a Subquery without using "with" clause - 不要将“物化”与“合并查询”混为一谈 我不是在谈论强制部分(更不用说“合并查询”),而是关于“Oracle 优化器 can ...”。我相信它可以。

以上是关于Oracle SQL WITH 语句是不是比 subselect 更好 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL CONNECT BY PRIOR ... SQL Server 中的 START WITH 语句

Oracle中with as的用法 zf

oracle 常用相关sql 语句

Oracle With As 查询

为啥在 Oracle 中使用 CASE 进行子选择比 JOIN WITH OR 更快

Oracle中with as的用法