2010-04-14 184 views
2

我们有一个饲料过程,每年的每一天运行。 作为其中的一部分,我们每天从表中删除每行(大约100万行),使用5个不同的存储过程重新填充它,然后提交事务。 这是我们所称的唯一提交语句。 突然删除已经开始进入约2小时完成。 删除也非常简单(从T_PROFILE_WORK删除) 这在过去的一年里效果很好,但在过去的一周里我注意到了这个问题。删除突然花费很长时间

任何帮助是极大的赞赏

回答

5

请参阅这太问题的答案:"oracle delete query taking too much time"

  1. 您可以通过另一个会话(很可能)被阻止。之前 删除,你应该确保没有人别的 锁定该行,如:问题选择 NULL FROM表名WHERE colname的=:值FOR UPDATE NOWAIT,
  2. 有可能是一个ON DELETE触发器,做额外的工作,
  3. 检查指向此表 (有script from AskTom, 将帮助您确定是否存在这样的未索引的外键存在)的未参考参考约束。

我会先检查#2和#3,它们是最容易诊断的。

+1

+1作为文森特出色答案的附录,并且解释汤姆凯特,“什么改变了?”如果删除语句确实有效并且现在没有更改导致此问题? – 2010-04-14 15:29:56

2

如果你只是想删除一切从表使用TRUNCATE而不是删除。

+0

恐怕我们不能那样做。当这张桌子被加载时,人们仍然使用我们的系统。如果我们截断了这个表,那么应用程序将一直是空的,直到这个表被加载并且提交完成。 (我知道的不是很好的建筑,但是我在这个解决方案实施后加入了这个项目) – Damien 2010-04-14 14:21:58

0

您如何从存储过程中填充第二个(也许是全局临时)表,然后在最终的MERGE中执行现有表。 不知道活动的细节,表格结构等,很难确定。但是你可能会发现它更快。

作为替代方案,如果您的企业版带有分区选项,请查看分区交换。

0

为了记录,这里是汤姆凯特的剧本,文森特马尔格拉特在接受的答案中提到过(这样你就不必通过gazillion的评论和更多的链接进行筛选)。

脚本产生全部所有表的列;您仍然必须找出哪些适用于要删除行的表以及哪些FK表具有最大基数。

否则,不是所有的命中都需要索引。

SELECT table_name, 
     constraint_name, 
      cname1 
     || NVL2 (cname2, ',' || cname2, NULL) 
     || NVL2 (cname3, ',' || cname3, NULL) 
     || NVL2 (cname4, ',' || cname4, NULL) 
     || NVL2 (cname5, ',' || cname5, NULL) 
     || NVL2 (cname6, ',' || cname6, NULL) 
     || NVL2 (cname7, ',' || cname7, NULL) 
     || NVL2 (cname8, ',' || cname8, NULL) 
      columns 
    FROM ( SELECT b.table_name, 
       b.constraint_name, 
       MAX (DECODE (position, 1, column_name, NULL)) cname1, 
       MAX (DECODE (position, 2, column_name, NULL)) cname2, 
       MAX (DECODE (position, 3, column_name, NULL)) cname3, 
       MAX (DECODE (position, 4, column_name, NULL)) cname4, 
       MAX (DECODE (position, 5, column_name, NULL)) cname5, 
       MAX (DECODE (position, 6, column_name, NULL)) cname6, 
       MAX (DECODE (position, 7, column_name, NULL)) cname7, 
       MAX (DECODE (position, 8, column_name, NULL)) cname8, 
       COUNT (*) col_cnt 
      FROM (SELECT SUBSTR (table_name, 1, 30) table_name, 
         SUBSTR (constraint_name, 1, 30) constraint_name, 
         SUBSTR (column_name, 1, 30) column_name, 
         position 
        FROM user_cons_columns) a, user_constraints b 
      WHERE a.constraint_name = b.constraint_name 
       AND b.constraint_type = 'R' 
     GROUP BY b.table_name, b.constraint_name) cons 
WHERE col_cnt > 
      ALL ( SELECT COUNT (*) 
        FROM user_ind_columns i 
        WHERE i.table_name = cons.table_name 
         AND i.column_name IN 
           (cname1, 
           cname2, 
           cname3, 
           cname4, 
           cname5, 
           cname6, 
           cname7, 
           cname8) 
         AND i.column_position <= cons.col_cnt 
       GROUP BY i.index_name);