Oracle 删除突然花了很长时间

Oracle 删除突然花了很长时间,oracle,performance,Oracle,Performance,我们有一个一年中每天都在运行的进料过程。 作为其中的一部分,我们每天从表中删除大约100万行,使用5个不同的存储过程重新填充它,然后提交事务。 这是我们唯一调用的commit语句。 突然之间,删除开始需要大约2个小时才能完成。 删除也是非常简单的从T_PROFILE_工作中删除 在过去的一年里,这一切都很顺利,但在过去的一周里,我注意到了这个问题 如果您只想删除表中的所有内容,请使用truncate而不是delete。请查看此问题的答案: 您很可能被另一个会话阻止。在你面前 删除你应该确保没有其

我们有一个一年中每天都在运行的进料过程。 作为其中的一部分,我们每天从表中删除大约100万行,使用5个不同的存储过程重新填充它,然后提交事务。 这是我们唯一调用的commit语句。 突然之间,删除开始需要大约2个小时才能完成。 删除也是非常简单的从T_PROFILE_工作中删除 在过去的一年里,这一切都很顺利,但在过去的一周里,我注意到了这个问题


如果您只想删除表中的所有内容,请使用truncate而不是delete。请查看此问题的答案:

您很可能被另一个会话阻止。在你面前 删除你应该确保没有其他人 正在锁定行,例如:问题选择 tablename中的NULL,其中 colname=:UPDATE NOWAIT的值, 可能有一个ON DELETE触发器执行额外的工作, 检查指向此表的未索引引用约束 有一个 将帮助您确定 存在未索引的外键。
首先,我要检查2和3,它们是最容易诊断的。

如果您有第二个全局临时表,您可以从存储过程中填充该表,并在最后合并到现有表中。 如果不知道活动的细节、表结构等,就很难确定。但你可能会发现它更快


另一种选择是,如果您的企业版带有分区选项,请查看分区交换。

记录在案,这是Tom Kyte的脚本,Vincent Malgrat在接受的答案中提到了该脚本,这样您就不必筛选大量的注释,也不必关注更多的链接

脚本生成所有表的所有列;您仍然需要确定哪些应用于要删除行的表,以及哪些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);

恐怕我们不能那样做。加载此表时,人们仍在使用我们的系统。如果我们截断了该表,则在加载该表并完成提交之前,应用程序将为空。我知道这不是一个很好的体系结构,但在这个解决方案被实现后,我加入了这个项目,并将+1作为Vincent的优秀答案的补充,并转述Tom Kyte的话,“什么改变了?”?如果delete语句确实起作用,但现在不起作用,是什么改变导致了这种情况?