一. 说明
如果对大表进行大规模的delete 和update,那么可以注意一下如下说明:
(1) 查看执行计划,如果说删除的记录很多,走索引的成本会比全表扫描更大,因为更新数据时还需要做一些约束校验和创建index entry。而且对于多CPU 情况,全表扫描还可以使用并行的特性。
Oracle Parallel Execution(并行执行)
(2)如果表上有索引,B-Tree 索引可以unusable索引,函数索引则disable 索引,等操作结束之后在rebuild索引。
(3)如果是大规模的delete,那么可能还需要注意一下高水位的问题,在允许的情况下,可以用alter table move 来降低高水位,同时注意rebuild 索引。
Oracle 高水位(HWM: High Water Mark) 说明
如果是OLTP的生产环境,对于禁用索引和高水位处理的操作要慎重。
二. 相关测试
--查看表中记录数
SYS@dave2(db2)> select count(*) from dave;
COUNT(*)
----------
3080115
--查看索引信息
SYS@dave2(db2)> select index_name from dba_indexes where table_name=''DAVE'';
INDEX_NAME
------------------------------
IDX _PRCODE
IDX _STATE
IDX _INSERT
SYS_C005469
--创建一个备份表,下次使用
SYS@dave2(db2)> create table dave1 as select /*+parallel(t,3)*/ * from dave t;
Table created.
--查看执行计划
SYS@dave2(db2)> explain plan for delete from dave where time_insert select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2615685836
---------------------------------------------------------------------------
| id | operation | name | rows | bytes | cost (%cpu)| time |
---------------------------------------------------------------------------
| 0 | delete statement | | 1369k| 26m| 7916 (3)| 00:01:35 |
| 1 | delete | dave | | | | |
|* 2 | table access full| dave | 1369k| 26m| 7916 (3)| 00:01:35 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - filter("time_insert" explain plan for update dave d set getcard_code=10 where state=2;
Explained.
SYS@dave2(db2)> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3706120077
-------------------------------------------------------------------------------
| id | operation | name | rows | bytes | cost (%cpu)| time |
-------------------------------------------------------------------------------
| 0 | update statement | | 96254 | 469k| 2533 (1)| 00:00:31 |
| 1 | update | dave | | | | |
|* 2 | index range scan| idx_state | 96254 | 469k| 194 (2)| 00:00:03 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - access("STATE"=2)
14 rows selected.
--禁用索引
SYS@dave2(db2)> alter index idx_state unusable;
Index altered.
SYS@dave2(db2)> select status from dba_indexes where index_name=''IDX_STATE'';
STATUS
--------
UNUSABLE
--如果是对进行delete 操作,那么相关的索引要全部禁用才起作用。
--更新数据
SYS@dave2(db2)> update dave d set state=10 where state=2;
101837 rows updated.
SYS@dave2(db2)> commit;
Commit complete.
--rebuild 索引
SYS@dave2(db2)> alter index idx_state rebuild;
Index altered.
Oracle alter index rebuild 说明