【发布时间】:2013-06-04 01:28:17
【问题描述】:
我正在编写一些数据库升级脚本,但遇到的查询花费的时间比我想象的要长:
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 服务器,它在升级过程中被关闭 - 所以我认为不会出现任何锁定问题。还有其他想法吗?
【问题讨论】:
-
删除语句确实不使用索引,正如您在
TABLE ACCESS (FULL)步骤中看到的那样(顺便说一句:请发布删除制表符的计划,目前列不对齐,它是几乎无法阅读) -
@a_horse_with_no_name - 但这应该没问题吧? WHERE 子句返回超过一半的行,使用索引并不会真正带来巨大的性能改进。
-
@a_horse_with_no_name - 嗯,当您复制和粘贴执行计划时,Aqua Data Studio 真的搞砸了格式。
-
如果该表有外键引用,而其他表有很多记录,delte查询会很慢。