一、oracle delete分批删除大量数据
1、delete 操作会产生redo log、undo log,这样是为了保证数据安全性,利于rollback。为防止undo表空间被撑爆,可以采用分批提交,代码如下:
declare
v_cnt number :=0;
begin
loop
delete from scoot.emp
where id>100
and rownum<500; --限制每次删除500行
v_cnt:=SQL%rowcount; --记录删除的行数
v_cnt:=SQL%rowcount; --记录删除的行数
commit;
exit when V_cnt<=0;
end loop;
end;
/
2、delete操作不会降低高水位线,而每次查询还是会扫描高水位线下的所有数据,这样查询效率不会因为delete之后,而提高查询效率。
使用truncate 删除数据,可以降低高水位线。但truncate是删除全表记录。不能带where条件。
2.1 查询高水位线语句,其中blocks表示高水位线:
select table_name,blocks,empty_blocks,num_rows
from dba_tables
where table_name='***';
删除完成后收集统计信息,再执行上述SQL,得出高水位线并没有下降。
利用dbms_stats包收集统计信息,只要是基于cbo的统计信息都可以用dbms_stats来收集。如下:
call dbms_stats.gather_table_stats('SCOTT','BIGTABLE');
另:利用analyze来收集一些dbms_stats收集不了的统计信息,如下:
analyze table tabname compute|estimate|delete statistics;
3、关于delete、update、insert三种DML操作,对redo、undo日志的产生量如下总结:
查看redo产生的语句:
SQL>select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
查看undo产生量的语句
SQL>select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
直观理解:
对于insert,redo中保存的是记录的所有值,undo中保存的是激励的rowid;
对于update,redo中保存的是rowid和修改后的值,undo中保存的是rowid和修改前的值;
对于delete,redo中保存的是删除行的rowid,undo中保存的是删除的完整记录。
1、delete 操作会产生redo log、undo log,这样是为了保证数据安全性,利于rollback。为防止undo表空间被撑爆,可以采用分批提交,代码如下:
declare
v_cnt number :=0;
begin
loop
delete from scoot.emp
where id>100
and rownum<500; --限制每次删除500行
v_cnt:=SQL%rowcount; --记录删除的行数
v_cnt:=SQL%rowcount; --记录删除的行数
commit;
exit when V_cnt<=0;
end loop;
end;
/
2、delete操作不会降低高水位线,而每次查询还是会扫描高水位线下的所有数据,这样查询效率不会因为delete之后,而提高查询效率。
使用truncate 删除数据,可以降低高水位线。但truncate是删除全表记录。不能带where条件。
2.1 查询高水位线语句,其中blocks表示高水位线:
select table_name,blocks,empty_blocks,num_rows
from dba_tables
where table_name='***';
删除完成后收集统计信息,再执行上述SQL,得出高水位线并没有下降。
利用dbms_stats包收集统计信息,只要是基于cbo的统计信息都可以用dbms_stats来收集。如下:
call dbms_stats.gather_table_stats('SCOTT','BIGTABLE');
另:利用analyze来收集一些dbms_stats收集不了的统计信息,如下:
analyze table tabname compute|estimate|delete statistics;
3、关于delete、update、insert三种DML操作,对redo、undo日志的产生量如下总结:
查看redo产生的语句:
SQL>select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='redo size';
查看undo产生量的语句
SQL>select b.name,a.value from v$mystat a,v$statname b where a.statistic#=b.statistic# and b.name='undo change vector size';
直观理解:
对于insert,redo中保存的是记录的所有值,undo中保存的是激励的rowid;
对于update,redo中保存的是rowid和修改后的值,undo中保存的是rowid和修改前的值;
对于delete,redo中保存的是删除行的rowid,undo中保存的是删除的完整记录。