3

我正在编写一些数据库升级脚本,并且遇到了一个比我认为应该花费更长的时间的查询:

DELETE FROM TPM_TASK WHERE TASK_TYPE='System';

这个查询需要一个多小时,我很好奇罪魁祸首是什么。

执行计划是:

DELETE STATEMENT    899.0   887 57793984    35481   1454721 899                             ALL_ROWS                                            
DELETE                                                      1   TPMDBO  TPM_TASK                                                        
TABLE ACCESS (FULL) 899.0   887 57793984    35481   1454721 1   TPMDBO  TPM_TASK    FULL    TABLE   ANALYZED    1   

跑步:

select count(1) FROM TPM_TASK WHERE TASK_TYPE='System';

计划是:

SELECT STATEMENT    92.0    89  14527479    1   7   92                  ALL_ROWS                                            
SORT (AGGREGATE)                1   7   1           AGGREGATE                                                   
INDEX (FAST FULL SCAN)  92.0    89  14527479    35481   248367  1   TPMDBO  TPM_TASK_TASK_TYPE  FAST FULL SCAN  INDEX   ANALYZED

这个查询非常快,给了我 44,202 行。表中的总行数为 71419。由于我删除了一半以上的行,我认为 Oracle 根本不会在删除时使用索引,这很好。无论如何,对 71,000 行的完整扫描仍然只需要几秒钟。

此表上没有触发器。没有任何其他表对该表具有 FK 约束,但是有一些视图和 SQL 函数使用该表。唯一使用该数据库的应用程序是我们的 Web 服务器,它在升级过程中被关闭 - 所以我认为不会出现任何锁定问题。还有其他想法吗?

4

1 回答 1

8

考虑到您给出的考虑,我唯一能想到的就是对这张表的某种UNINDEXED REFERENCE CONSTRAINT引用。尝试对表运行此脚本,它应该为您提供一份报告,其中包含它找到的任何未索引的引用。这个操作当然没有理由需要这么长时间。

于 2013-06-07T16:54:03.613 回答