有关优化此多层(具有多层子查询)SQL 查询的提示

Posted

技术标签:

【中文标题】有关优化此多层(具有多层子查询)SQL 查询的提示【英文标题】:Tips about optimizing this multi-layered (with many layers of subqueries) SQL query 【发布时间】:2017-12-01 16:38:39 【问题描述】:

对于这个 SQL 查询,我需要您的帮助。我有一个包含 6 层子查询的查询,目前的结构是这样的。我期待建议如何:

    减少层数而不重复相同的语句(例如,我可以将 'case when E>200' 替换为 '(Case when T2.BB >100 then B+C else B+D end) > 200 ' 并在第 1 层中编写语句,从而消除第 2 层。我不能这样做,因为在我的原始查询中,我有一个计算列基于其子查询中的另一个计算列,然后基于另一个计算子查询中的列...所以重复代码 5/6 次会让我感到困惑并让我发疯...

    避免使用 select 2.,选择 1.,同时仍将所有列 (F,E,A,B,C,D,T2.BB) 保留在最终输出中。我想这样做是因为在我的原始查询中有 5 个选择。* - 我觉得这会导致服务器做很多冗余工作并减慢查询执行速度。

非常感谢您的帮助!

Select 
    2.*,
    case when E > 200 then 'OK' else 'OH NO' end F
From
    (Select 
         1.*,
         Case when T2.BB >100 then B+C else B+D end E
     From
         (Select
              A, B, C, D, T2.BB
          From 
              T1
          Join 
              T2 on T1.A = T2.AA) 1
    ) 2

【问题讨论】:

我们需要知道您使用的是什么数据库 “我觉得这会导致服务器做很多多余的工作”只有分析查询计划才能确定,因为 engien 可以在后台对其进行优化 嗨@gjvdkamp。这是 Amazon Redshift。 【参考方案1】:

尝试 WITH 语句,它们看起来更简洁,因为它们有助于保持应用逻辑的顺序,所以它看起来像这样:

WITH
t1 as (
    select ...
    from src_table
)
,t2 as (
    select *, ...
    from t1
)
<<as much layers as needed>>

此外,如果您需要在 2 个不同的地方重用某些东西,您可以从任何后续语句中引用前面的 WITH 语句,即将该逻辑封装在一个地方

【讨论】:

嗨,亚历克斯。感谢您的提示。我使用了您的方法并提高了 SQL 执行性能。

以上是关于有关优化此多层(具有多层子查询)SQL 查询的提示的主要内容,如果未能解决你的问题,请参考以下文章

SQL 优化 - 多层嵌套逻辑先行

sql 语句多层嵌套查询 使用别名 字段无效,如何解决(有图)

如何在 symfony 中查询多层链接表

有关 SQL Server 中的 SQL 查询提示的详细信息

js解析多层嵌套的json,取出所有父元素属性和遍历所有子元素

oracle子查询