【问题标题】: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。这个简化的版本,很好地简化了。在花费数小时将其从一个转换为另一个之前,我只是在寻找建议。

标签: sql oracle subquery common-table-expression query-performance


【解决方案1】:

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

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

【讨论】:

  • 我相信第二点也适用于非 CTE 子查询。
  • @trincot,我不知道,似乎不太清楚:Materialize a Subquery without using "with" clause - 不要将“物化”与“合并查询”混为一谈
  • 我不是在谈论强制部分(更不用说“合并查询”),而是关于“Oracle 优化器 can ...”。我相信它可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 2012-05-10
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多