Oracle 大规模 delete,update 操作 注意事项
一.
如果是OLTP的生产环境,对于禁用索引和高水位处理的操作要慎重。
二. 相关测试
--查看表中记录数
SYS@dave2(db2)> select count(*) from dave;
----------
--查看索引信息
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 * from dave t;
Table created.
--查看执行计划
SYS@dave2(db2)> explain plan for delete from dave where time_insert<to_date('2011-5-1','yyyy-mm-dd');
SYS@dave2(db2)> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2615685836
---------------------------------------------------------------------------
| id
---------------------------------------------------------------------------
|
|
|*
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
15 rows selected.
--查看走执行计划的大规模update 操作
SYS@dave2(db2)> 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
-------------------------------------------------------------------------------
|
|
|*
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
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
101837 rows updated.
SYS@dave2(db2)> commit;
Commit complete.
--rebuild 索引
SYS@dave2(db2)> alter index idx_state rebuild;
Index altered.
Oracle alter index rebuild 说明
http://blog.csdn.net/tianlesoftware/archive/2011/06/12/6538928.aspx
-- 查看高水位
SYS@dave2(db2)> select num_rows,blocks,empty_blocks from dba_tables where table_name='DAVE';
---------- ---------- ------------
num_rows 的值只有做过统计信息收集之后才有,如果该值与count(*) 差距太大,就说明需要重新进行收集了。
empty_blocks 参数只有使用analyze 收集统计信息才有,使用dbms_stats 收集不到这个参数的信息。 如果empty_blocks 较多,就说明有高水位了。
SYS@dave2(db2)> analyze table dave compute statistics;
Table analyzed.
SYS@dave2(db2)> select num_rows,blocks,empty_blocks from dba_tables where table_name='DAVE';
---------- ---------- ------------
有关统计信息更多内容参考:
--处理高水位
SYS@dave2(db2)> alter table dave move;
Table altered.
--move 会使所有索引失效,需要重新rebuild
SYS@dave2(db2)> select index_name,status from dba_indexes where table_name='DAVE';
INDEX_NAME
------------------------------ --------
IDX_PRCODE
IDX_STATE
IDX_INSERT
SYS_C005469
--rebuild 索引
SYS@dave2(db2)> alter index IDX_PRCODE rebuild;
Index altered.
SYS@dave2(db2)> alter index IDX_STATE rebuild;
Index altered.
SYS@dave2(db2)> alter index idx_insert rebuild;
Index altered.
SYS@dave2(db2)> alter index SYS_C005469 rebuild;
Index altered.
SYS@dave2(db2)> select index_name,status from dba_indexes where table_name='DAVE';
INDEX_NAME
------------------------------ --------
IDX_PRCODE
IDX_STATE
IDX_INSERT
SYS_C005469
-- 使用analyze 分析表
SYS@dave2(db2)>
Table analyzed.
SYS@dave2(db2)> select num_rows,blocks,empty_blocks from dba_tables where table_name='DAVE';
---------- ---------- ------------
因为我这里没有进行大量的delete 操作,效果很有限。