sql - 从空表中删除永远

标签 sql performance oracle plsql

我有一个以前有大量行的空表。

该表有大约 10 个列和其中许多列的索引,以及多个列的索引。

DELETE FROM item WHERE 1=1

这大约需要 40 秒才能完成
SELECT * FROM item

这需要 4 秒。

SELECT * FROM ITEM 的执行计划显示如下;
SQL> select * from midas_item;

no rows selected

Elapsed: 00:00:04.29

Execution Plan
----------------------------------------------------------
 0      SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73
      80)

1    0   TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte
      s=7380)





Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
   5263  consistent gets
   5252  physical reads
      0  redo size
   1030  bytes sent via SQL*Net to client
    372  bytes received via SQL*Net from client
      1  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      0  rows processed

知道为什么这些会花费这么长时间以及如何解决它,将不胜感激!

最佳答案

一种可能性是锁。也就是说,表中有一行已被另一个删除提交并锁定。您的删除坐在并等待锁定。提交锁定事务后,您的删除就可以完成了。

第二种可能性是您首先运行了删除,它将块从磁盘提取到缓存中(这需要时间)。 When the select ran, the data was in the cache and so ran quicker.我认为这不太可能,因为您选择的统计数据表明“5252 物理读取”,因此它没有从 SGA 缓存中获取它们。不过,可能涉及磁盘缓存。

第三种可能性是有一个 BEFORE/AFTER DELETE 触发器(不是 FOR EACH ROW)做了一些事情。

第四种可能性是 DELETE 导致延迟块清除。当行被实际删除时,如果它们在提交之前被写入磁盘,它们仍然具有锁定/事务信息。您的删除随之而来,读取块,查看现在过时的事务信息,将其删除并重新写入块。

第五种可能性是争用。也许在删除的同时发生了更多的事情。

很多可能性。如果您可以重现它,则使用等待事件进行跟踪并通过 TKPROF 运行它。

关于sql - 从空表中删除永远,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2495233/

相关文章:

sql - 如何在 WHERE 子句中引用列别名

sql - 如何从表中删除日期早于 2006 年的数据

Oracle 18c XE : Connecting to a PDB using SID (for legacy application)

sql - Oracle - 发生异常时以字符串形式获取 SQL

mysql - 数据库触发器是如何在 SQL 数据库引擎中实现的?

php - Symfony、Doctrine 和 "Proxy Classes are always regenerating"

python - 如何在 networkx 中高效地生成多个具有随机边权重的随机图

php - 如何计算在查询的 SELECT 部分中生成的列?

sql - ORA-00918:列在SELECT中的定义不明确*

css - Angular 2 - 每个组件一个大的 css 文件或一个文件