Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么Oracle上的删除查询速度如此之慢?_Sql_Oracle_Oracle11g - Fatal编程技术网

Sql 为什么Oracle上的删除查询速度如此之慢?

Sql 为什么Oracle上的删除查询速度如此之慢?,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我正在编写一些数据库升级脚本,并且遇到了一个查询,它比我认为的要长得多: DELETE FROM TPM_TASK WHERE TASK_TYPE='System'; 这个问题需要一个多小时,我很好奇罪魁祸首是什么 执行计划是: DELETE STATEMENT 899.0 887 57793984 35481 1454721 899 ALL_ROWS

我正在编写一些数据库升级脚本,并且遇到了一个查询,它比我认为的要长得多:

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
这个查询相当快,给了我44202行。表中的行总数为71419。因为我删除了超过一半的行,所以我认为Oracle根本不需要在delete上使用索引,这很好。对71000行的完整扫描无论如何只需要几秒钟


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

记住你给出的考虑,我唯一能想到的是引用此表的某种
未索引引用约束。尝试对该表运行,它将为您提供一个包含它找到的任何未索引引用的报告。当然,没有理由认为此操作需要如此长的时间。

delete语句确实没有使用索引,正如您在
表访问(完整)
步骤中看到的那样(顺便说一句:请在发布计划时删除制表符,目前列没有对齐,实际上无法读取)@一匹没有名字的马-但那应该没问题吧?WHERE子句返回了超过一半的行,使用索引并不是一个很大的性能改进。@a_horse_和_no_name-Hmm,Aqua Data Studio在复制和粘贴执行计划时确实会搞砸格式。如果有外键引用该表,而其他表有大量记录,则delte查询会很慢。是的,那份报告有56行。你是说有些东西引用了
TPM_任务
,但没有索引,所以它必须对每个单独的删除进行完整的表扫描?啊,是的,就是这样!实际上,有两个表引用了
TPM_任务的主键,它们没有索引。我在这些行上创建了一个索引,然后手动删除了引用
TPM_任务中即将删除的行的行(避免级联删除)。在此之后,
TPM_任务
上的delete语句花费了大约10秒。这是一个极好的例子,证明不直接查询列并不意味着不需要在列上建立索引。@MikeChristensen-很高兴我能提供帮助,我花了很多时间优化Oracle查询,并经常遇到索引和引用问题。太好了!但是你说“这个表上没有其他表有FK约束”@wolφi可能没有FK约束那么明显。例如,引用另一个表的表上的某种触发器。