走如果用append插入1亿行,回滚的时候会发生什么问题?
测试:
(1)第一个会话下执行
CREATE TABLE t (a INTEGER);
insert into t select a.object_id from dba_objects a,dba_objects b where rownum <1000000;
(2)新开一个会话执行:
create TABLE t_append (a INTEGER);
insert /+append/into t_append select a.object_id from dba_objects a,dba_objects b where rownum <1000000;
查看append插入的会话的SID
v
SID
194
查看两个表占用的回滚段
SELECT s.USERNAME,s.SID,s.SERIAL#,t.UBAFIL “UBA filenum”, t.UBABLK
“UBA Block number”,t.USED_UBLK “Number os undo Blocks Used”,
t.START_TIME,t.STATUS,t.START_SCNB,t.XIDUSN RollID,r.NAME RollName
FROM v
WHERE s.SADDR=t.SES_ADDR AND t.XIDUSN=r.usn
AND s.username=USER;
可以看到APPEND只占用一个回滚段。
现在将两个会话分别rollback或者commit,在两张表创建索引,再执行插入
create index idx_t on t(A);
create index idx_t_append on t_append(A);
查看回滚段
总结:append插入时如果这一列是有索引的话,是分插到不同的索引段,是会占很多索引段的,append直接插入到表没有索引的时候,直接推高高水位。
append的优点:1、减少了redo(redo分为两部分,一部分是对于块的redo,一部分是对于undo的redo,这里减少了undo就减少redo。如果这个表设置的是nologging,dml完全不写redo) 2、减少了undo 3、从高水位插入会比较快(减少了查找块的时间)4、直接写到磁盘,不经过buffer,但是IO增大了