【问题标题】:Oracle Query Performance ImprovementOracle 查询性能改进
【发布时间】:2019-02-13 12:50:55
【问题描述】:

我有两个结构如下的表

INPUTFILELOG 列为

FILE_ID
RECORD_SEQ
ACCOUNT
CHILD_ACCOUNT

PURGE 列为

ACCOUNT
DATE
DETAILS

查询

delete from INPUTFILELOG il
where  exists
       ( select 1 from PURGE po
         where  po.account = ':NUMBER'
         and    ( po.account = il.account OR po.account = il.child_account ) )

即使 PURGE.ACCOUNTINPUTFILELOG.ACCOUNTINPUTFILELOG.CHILD_ACCOUNT 上有索引,上述查询的性能也很差。有人可以 请帮忙?

更新

我尝试了以下查询。它看起来不错吗?有没有更好的处理方法?

delete from INPUTLOG sif
where  exists
       ( select t.fileno, t.rec
         from   ( SELECT sif2.FILE_ID as fileno, sif2.RECORD_SEQ as rec
                  FROM   purge po 
                         INNER JOIN INPUTLOG sif2 
                              ON (   po.ACCOUNT = sif2.ACCOUNT
                                  OR po.ACCOUNT = sif2.CHILD_ACCOUNT )
                  where  po.account = ':NUMBER' ) t
         WHERE  sif.FILE_ID = t.FILEno
         AND    sif.record_seq = t.rec)

【问题讨论】:

  • 请将代码格式化为代码。看看你的其他帖子如何做到这一点。
  • 嗨 Ram,一些提示:1)如果您将删除转换为选择和检查,这是否也需要时间 - 在这种情况下,这很好地表明查询肯定是坏的,否则还有有可能是删除操作需要时间,而不是查询的错误。 2)这个糟糕的查询实际上删除了多少数据,那么大吗? 3)发布查询的执行计划并验证是否有改进的机会。
  • 嗨,我错过了一些要点 1) 当只包含一个条件(在 OR 中)时,查询性能会提高。如果两者都包括在内,则会发生 INPUTFILELOG 的全表扫描。 2) 对于作为主变量传递的每个帐户,大约有 100 条记录被删除。 3 ) 相同的查询在 DB2 上运行良好。
  • account 对于purge 表来说是唯一的还是可以有重复的?
  • 是的帐户在清除表中是唯一的

标签: oracle performance indexing


【解决方案1】:

根据您的最新输入,我建议将原始查询分解为以下两个查询,并验证它们是否在功能上正常(我认为应该如此)并验证它们的性能。我认为以下两个可能表现更好,这里的问题可能是由于导致全表扫描的“OR OPERATOR”。

DELETE FROM INPUTLOG il
      WHERE EXISTS
               (SELECT 1
                  FROM PURGE po
                 WHERE po.account = ':NUMBER' AND (po.account = il.account))


DELETE FROM INPUTLOG il
      WHERE EXISTS
               (SELECT 1
                  FROM PURGE po
                 WHERE     po.account = ':NUMBER'
                       AND (po.account = il.child_account))

【讨论】:

  • 同意您的建议有效。可以使用单个查询来完成吗?我尝试了一次方法并更新了问题。能否请您提供您的意见
  • 嗨 Ram,我不确定它是否有效,您是最好的人选,因为您拥有可以验证执行计划和时间细节的系统。我有点怀疑,因为我看到 OR 子句可能会导致问题,但我在这里不是 100% 确定。请您仔细核实并决定。如果你发现执行计划和时间不好,那么你可以去使用避免问题的两个查询的方法。谢谢。
  • 我的意思是,验证您修改后的查询是否仍然发生全表扫描或非常大的索引范围扫描等详细信息。
【解决方案2】:

您只想删除一个帐户。如果表中只有十个帐户,那么全表扫描将是删除如此大比例的表数据的最佳方法。但是您说,仅删除帐户或子帐户时,删除速度要快得多。我收集到这两个删除的加起来时间比你的组合查询要短得多。所以很明显会使用一个索引,这意味着它必须只是被删除的表的一小部分。

两个想法:

  1. 好吧,显然您可以只运行两个删除语句而不是一个,并且已经实现了您想要的。
  2. 非常清楚地向 DBMS 显示它只是您想从表 INPUTFILELOGinputfilelog.account = ...)中删除的一个帐户。

因此:

delete from inputfilelog where account =
  (select account from purge where account = ':NUMBER');

delete from inputfilelog where child_account = 
  (select account from purge where account = ':NUMBER');

也许= 甚至足以使组合的statemet 运行得更快(但使用两个索引与OR 组合通常不是)。

delete from inputfilelog
where account = (select account from purge where account = ':NUMBER')
or child_account = (select account from purge where account = ':NUMBER');

inputfilelog.account = ... 的另一种方法:

delete from inputfilelog
where (account = :NUMBER or child_account = :NUMBER)
and exists (select * from purge where account = :NUMBER);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2015-01-17
    • 1970-01-01
    • 2021-05-22
    相关资源
    最近更新 更多