Wil*_*ill 5 sql oracle performance plsql
我有一个以前有大量行的空表.
该表在其中许多列上有大约10列和索引,以及多列上的索引.
DELETE FROM item WHERE 1=1
Run Code Online (Sandbox Code Playgroud)
这大约需要40秒才能完成
SELECT * FROM item
Run Code Online (Sandbox Code Playgroud)
这需要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
Run Code Online (Sandbox Code Playgroud)
任何想法为什么这些将花费这么长时间,如何解决它将非常感谢!!
一种可能性是锁。也就是说,表中有一行已被另一个删除提交并锁定。您的删除坐在并等待锁定。提交锁定事务后,您的删除就可以完成了。
第二种可能性是您首先运行了删除,它将块从磁盘提取到缓存中(这需要时间)。When the select ran, the data was in the cache and so ran quicker. 我认为这不太可能,因为您选择的统计数据表明“5252 物理读取”,因此它没有从 SGA 缓存中获取它们。不过,可能涉及磁盘缓存。
第三种可能性是有一个 BEFORE/AFTER DELETE 触发器(不是 FOR EACH ROW)做了一些事情。
第四种可能性是 DELETE 导致延迟块清除。当这些行被实际删除时,如果它们在提交之前被写入磁盘,它们仍然会有锁/事务信息。您的删除随之而来,读取块,查看现在过时的事务信息,将其删除并重新写入块。
第五种可能性是争用。也许在删除的同时发生了更多的事情。
很多可能性。如果您可以重现它,则使用等待事件进行跟踪并通过 TKPROF 运行它。
select只是进行全表扫描。另一方面(在 Oracle 中)删除必须将整个删除的行存储在回滚段中,以便允许您稍后撤消更改(因此它甚至可能比插入慢)。
您可以在 Ask Tom 论坛上找到与此相关的非常长且有用的讨论。根据您的业务案例,也许您可以应用更多技术。
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689
| 归档时间: |
|
| 查看次数: |
2598 次 |
| 最近记录: |