【问题标题】:Using Union All performance degrades in Oracle View在 Oracle View 中使用 Union All 性能会降低
【发布时间】:2021-02-10 18:30:07
【问题描述】:

我在 oracle 视图下创建了我在 union all 中添加了 select 查询,所有这些都可以正常工作,达到预期的结果,但突然视图的性能变得非常慢。表 IS_ID 包含 510000 条记录。

我真的不明白,通过添加这个 UNION ALL 选择查询只是在视图中添加了 400 行,但仍然是为什么现在性能变得非常慢。性能缓慢的主要原因是union all 中的以下语句阻塞了视图。我可以将 IS_TRE 视图的 union all 或以下语句分发到不同的视图中以提高性能,或者我如何重写以下语句来提高性能?

WHERE
        FUND_ISIN NOT IN
                         (
                         SELECT DISTINCT
                             FUND_ISIN
                         FROM
                             IS_ID
                         WHERE
                             MEMBER_DESCR ='O')

【问题讨论】:

  • 是有性能问题的查询select * from is_tre 还是您的实际查询在做其他事情?
  • 我在另一个视图 TT_RE 中使用此视图,该视图导致性能问题...如果我从 IS_TRE 视图中删除此部分,则另一个视图 TT_RE 没有遇到任何性能问题...主要问题在于这条语句:FUND_ISIN NOT IN (SELECT DISTINCT FUND_ISIN FROM IS_ID WHERE MEMBER_DESCR ='O')
  • 我认为上面的语句以某种方式阻塞了视图 IS_TRE ..我们可以在不同的视图中分离和分配联合,以及联合的内部选择查询部分,看看它是否提高了性能?
  • 那么慢的查询是指另一个视图依赖于这个视图的查询吗?您需要了解 Oracle 接受整个查询,并且可以在任何合法的情况下重写它,以使其发挥最佳性能。它能够做一些事情并为您的要求提出一个快速执行计划,而无需额外的union all(它对查询转换有各种限制 - 如果您能看到查询,就可以解决)。
  • “阻塞视图”没有任何意义,您可能的意思是计算额外设置的行所需的额外工作会增加执行时间。 “我们可以从不同的角度分离和分配工会……”你是什么意思?我建议你包括所有需要的视图定义和完整的 SQL 语句,这很慢。奖励积分包括有和没有额外union all的执行计划。

标签: oracle select view union-all


【解决方案1】:

你可以试试NOT EXISTS看看是否有帮助

FROM
    IS_ID OUT_Q
    WHERE
    FUND_ISIN NOT EXISTS
                     (
                     SELECT 'X' FROM IS_ID IN_Q
                     WHERE MEMBER_IN_Q.DESCR ='O'  AND OUT_Q.COLUMNS_MAKING_UP_THE_UNIQE_KEY
                          = IN_Q.COLUMNS_MAKING_UP_THE_UNIQE_KEY
)

【讨论】:

    【解决方案2】:

    我已经向您介绍了为什么您要分享的内容如此之多。但总的来说,这是免费的

    SELECT 
        FUND_ISIN,    
        MAX(FUND_QUOTE_CRNY),    
        'O' AS MEMBER_DESCR,
        100 - SUM(MEMBER_RATIO),
        'Other total'
    FROM
        IS_ID 
        WHERE
        FUND_ISIN NOT IN
                         (
                         SELECT DISTINCT
                             FUND_ISIN
                         FROM
                             IS_ID
                         WHERE
                             MEMBER_DESCR ='O')
    GROUP BY
        FUND_ISIN;
    

    可以改写为

    SELECT 
        FUND_ISIN,    
        MAX(FUND_QUOTE_CRNY),    
        'O' AS MEMBER_DESCR,
        100 - SUM(MEMBER_RATIO),
        'Other total'
    FROM
        IS_ID
    GROUP BY
        FUND_ISIN
    HAVING sum(case when MEMBER_DESCR ='O' then 1 else 0 end) = 0
    

    而且它可能会表现得更好。

    这是否会对您的实际情况产生影响是未知的。

    【讨论】:

    • 感谢它现在的工作和表现比预期的好得多
    • 现在我们知道性能会随着 sql 更改而提高...您是否还看到任何其他选项,我们可以尝试替代此视图以提高性能,或者可能是 sql 更改?然后我可以测试这个......
    • 除非您提供更多信息,否则我只会在黑暗中刺伤,我每人每天只使用一次水晶球。我们需要您正在执行的完整 SQL 以及相关的视图定义和完整的执行计划。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多