T 2 65536
T 3 65536
T 4 65536
这里我们创建了一张表,分配了5个extents。
SQL> delete from t;
已删除979行。
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='T';
SEGMENT_NA EXTENT_ID BYTES
---------- ---------- ----------
T 0 65536
T 1 65536
T 2 65536
T 3 65536
T 4 65536
这里删除了表里的数据,但是查询,依然占据5个extents。因为delete不会收缩表空间,不能降低高水位。
SQL> insert into t select * from user_tables;
已创建980行。
SQL> commit;
提交完成。
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='T';
SEGMENT_NA EXTENT_ID BYTES
---------- ---------- ----------
T 0 65536
T 1 65536
T 2 65536
T 3 65536
T 4 65536
用传统方式插入,数据被分配到已有的空闲空间里。
SQL> delete from t;
已删除980行。
SQL> commit;
提交完成。
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='T';
SEGMENT_NA EXTENT_ID BYTES
---------- ---------- ----------
T 0 65536
T 1 65536
T 2 65536
T 3 65536
T 4 65536
删除数据,用append直接插入看一下。
SQL> insert /*+append */ into t select * from user_tables;
已创建980行。
SQL> commit;
提交完成。
SQL> select segment_name,extent_id,bytes from user_extents where segment_name='T';
SEGMENT_NA EXTENT_ID BYTES
---------- ---------- ----------
T 0 65536
T 1 65536
T 2 65536
T 3 65536
T 4 65536
T 5 65536
T 6 65536
T 7 65536
T 8 65536
T 9 65536
已选择10行。
从结果可以看出,直接加载方式时,虽然表中有很多空的数据块,Oracle 仍然会额外的分配4个extent用于直接加载数据。
直接加载的数据放在表的高水位(High water Mark:hwm)以上,当直接加载完成后,Oracle 将表的高水位线移到新加入的数据之后,这样新的数据就可以被用户使用了。
7.1 直接加载和REDO
直接加载在logging模式下,与传统加载方式产生的redo 日志差别不大,因为当一个表有logging属性时,即使使用直接加载,所有改变的数据依然要产生redo,实际上是所有修改的数据块全部记录redo,以便于以后的恢复,这时候直接加载并没有太大的优势。
直接加载最常见的是和nologging一起使用,这时候可以有效地减少redo 的生成量。 注意的是,在这种情况下,直接加载的数据块是不产生redo的,只有一些其他改变的数据产生一些redo,比如表空间分配需要修改字典表或者修改段头数据块,这些修改会产生少量的redo。
实际上,对于nologging 方式的直接加载,undo 的数据量也产生的很少,因为直接加载的数据并不会在回滚段中记录,这些记录位于高水位之上,在事务提交之前,对于其他用户来说是不可见的,所以不需要产生undo,事务提交时,Oracle 将表的高水位线移到新的数据之后,如果事务回滚,只需要保持高水位线不动即可,就好像什么都没有发生一样。
注意,由于在nologging模式下,redo 不记录数据修改的信息,所以直接加载完后,需要立即进行相关的备份操作,因为这些数据没有记录在归档日志中,一旦数据损坏,只能用备份来恢复,而不能使用归档恢复。
Logging模式下示例:
SQL> set autot trace stat;
SQL> insert /*+append */ into t select * from user_tables;
已创建980行。
统计信息
----------------------------------------------------------
132 recursive calls
87 db block gets
8967 consistent gets
0 physical reads
286572 redo size
911 bytes sent via SQL*Net to client
1017 by