【问题标题】:Oracle Sub-select taking a long timeOracle Sub-select 耗时较长
【发布时间】:2013-02-05 15:11:08
【问题描述】:

我有一个包含两级子选择的 SQL 查询。这需要太多时间。

查询如下:

   select * from DALDBO.V_COUNTRY_DERIV_SUMMARY_XREF
    where calculation_context_key = 130205268077
    and DERIV_POSITION_KEY in 
          (select ctry_risk_derivs_psn_key 
            from DALDBO.V_COUNTRY_DERIV_PSN
            where calculation_context_key = 130111216755 
            --and ctry_risk_derivs_psn_key = 76296412
            and CREDIT_PRODUCT_TYPE = 'SWP OP'
            and CALC_OBLIGOR_COUNTRY_OF_ASSETS in 
                (select ctry_cd 
                 from DALDBO.V_PSN_COUNTRY
                 where calculation_context_key = 130134216755 
                --and ctry_risk_derivs_psn_key = 76296412
                )
           )

这些桌子很大!有没有可用的优化?

【问题讨论】:

  • 信息太少了。架构是什么?现有的索引是什么?查询计划是什么样的?在这种情况下,什么是“巨大”?此外,您的查询不完整,它至少缺少一个结束括号(注释掉的那个?)
  • 1.所有这些模式都在主键上建立索引。就像 V_COUNTRY_DERIV_SUMMARY_XREF 有 V_COUNTRY_DERIV_SUMMARY_XREF_key 2。我们可以忽略这个表:DALDBO.V_PSN_COUNTRY。其他两个都比较大 3. 查询计划我不确定。
  • 为什么不加入? (而不是子选择)。但正如 Joachim 所说,信息太少了
  • 在过去的 6-7 个月里,我们每天在这些表中输入近百万条记录!!!
  • @Vivek 我们猜不出你的主键是什么,所以告诉我们这些表是在主键上索引的并不能告诉我们太多。您的表名也以V_ 开头,这让我想知道,这些表或视图是这些表还是视图(因为许多地方倾向于使用v_ 表示视图)。您的表是否有一个索引,涵盖了您在此处过滤的所有列以及每个子选择会产生多少行)?

标签: sql performance oracle optimization


【解决方案1】:

在不了解您的表或视图定义、索引等的情况下,我将首先查看子选择并确保它们以最佳方式执行。我还想知道每个子选择返回了多少值,因为这会影响性能。

calculation_context_key 如何用于从 V_COUNTRY_DERIV_PSN 和 V_PSN_COUNTRY 检索行?是最优的执行计划吗?

如何在 V_COUNTRY_DERIV_SUMMARY_XREF 中使用 DERIV_POSITION_KEY 和 CALC_OBLIGOR_COUNTRY_OF_ASSETS 来检索行?再次查看解释计划。

【讨论】:

  • 底部的子选择返回 10 个国家,顶部的子选择返回大约 3800 行。并且所有的键都是可敬的表的索引,并在其他表中用作外键以符合关联关系。
【解决方案2】:

首先,您可以使用内部连接(而不是子选择)编写此查询吗?

select  A.* 
from    DALDBO.V_COUNTRY_DERIV_SUMMARY_XREF a, 
    DALDBO.V_COUNTRY_DERIV_PSN b,
    DALDBO.V_PSN_COUNTRY c
where   calculation_context_key = 130205268077
and a.DERIV_POSITION_KEY = b.ctry_risk_derivs_psn_key 
and b.calculation_context_key = 130111216755 
--and   b.ctry_risk_derivs_psn_key = 76296412
and b.CREDIT_PRODUCT_TYPE = 'SWP OP'
and     b.CALC_OBLIGOR_COUNTRY_OF_ASSETS = c.ctry_cd 
and c.calculation_context_key = 130134216755 
--and   c.ctry_risk_derivs_psn_key = 76296412

其次,最佳实践表明,当您不从子选择中的表中查询任何数据时,最好使用 EXISTS 而不是 IN。新版本的 oracle 会自动将整个内容重写为内部连接。

最后,在不了解您的数据和您正在尝试做什么的情况下,我建议您尽可能少地尝试使用视图 - 如果您可以查询下属表,那将是最好的,您可能会看到立即的性能改进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 2016-06-07
    • 1970-01-01
    • 2016-05-21
    相关资源
    最近更新 更多