【发布时间】:2013-02-21 12:43:26
【问题描述】:
考虑表格:
Table Name:ORDER
Columns: (ID (PK), ORDER_NUM, ORDER_STATUS, etc...)
Index(ORDER_IDX) exists on (ORDER_NUM, ORDER_STATUS) together.
There are various FKs too, on which Indexes exist as well.
There are about 2 million rows in the table.
考虑 SQL 查询:
DELETE from ORDER where ORDER_NUM=234234;
对于特定的 ORDER_NUM 值,DELETE 查询第一次运行非常慢(删除 200 行几乎需要 5 秒)。
但如果我回滚并再次运行 DELETE Query same ORDER_NUM,DELETE QUERY 现在会在 200 毫秒内运行。
因此,对于提供给此查询的任何 新 ORDER_NUM - 查询运行非常缓慢。
我可以做些什么来固定第一次查询本身?我必须重建索引吗?还是别的什么?
我正在使用 Oracle SQL 客户端工具(如 TOAD/SQL-Developer)对此进行测试 - 在实际使用它的 Web 应用程序中看到这种缓慢行为之后。
编辑>>>
SET AUTOTRACE ON 的结果
QUERY 首次运行时
3 user calls
0 physical read total multi block requests
4915200 physical read total bytes
4915200 cell physical IO interconnect bytes
0 commit cleanout failures: block lost
0 IMU commits
1 IMU Flushes
0 IMU contention
0 IMU bind flushes
0 IMU mbu flush
查询运行的第二次
3 user calls
0 physical read total multi block requests
0 physical read total bytes
0 cell physical IO interconnect bytes
0 commit cleanout failures: block lost
0 IMU commits
1 IMU Flushes
0 IMU contention
0 IMU bind flushes
0 IMU mbu flush
解释计划 - 在第一次和第二次运行中完全相同 - 如下所示:
ID OPERATION NAME ROWS Bytes Cost(%CPU) Time<br>
=======================================================================================
0 DELETE Statement 49 2891 41 (0) 00:00:01
1 DELETE ORDER
2 INDEX RANGE SCAN ORDER_IDX 49 2891 3 (0) 00:00:01
您可以在第一次看到非常高的物理读取。
我可以做些什么来帮助解决这种情况吗?
【问题讨论】:
-
可缓存数据?当你重做时 - 它们仍然存在 - 在内存中,另一个问题是索引集群中有许多分裂 - 需要重新组织......
-
@jasper:insert 200 rows commit 然后运行此命令
ANALYZE TABLE <TABLE_NAME> COMPUTE STATISTICS;然后删除记录。现在检查删除所需的时间 -
Simon 可能有答案(您的数据现在已缓存),但您需要显示此语句的执行计划。另外,这张桌子上有触发器吗?您在使用 Exadata 吗?您是否有任何
on delete cascadeFK 引用此表? -
请发布解释计划!另外,您要从中删除的表上是否有任何触发器?
-
第一个查询执行物理读取,第二个执行不执行。这就是问题的答案——数据被缓存了。