高水位线及直接装入数据:
实验一:delect删除表数据行,高水位线不发生变化:
1、scott用户下先模拟创建一张表,并插入数据:
SQL> select count(*) from dba_objects;
COUNT(*)
----------
86413
SQL> create table scott.sales as select * from dba_objects;
Table created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> insert into scott.sales select * from dba_objects;
86414 rows created.
SQL> select count(*) from scott.sales;
COUNT(*)
----------
1382624
2、查询scott用户中刚刚创建的sales表所占用的磁盘空间。
SQL> select blocks from dba_segments where owner='SCOTT' and segment_name='SALES';
BLOCKS
----------
20352
SQL> select num_rows,blocks,empty_blocks from dba_tables where owner='SCOTT' and table_name='SALES';
no rows selected
3、使用analyze命令手机scott用户中sales表的统计信息。
备注:上面的数据字典dba_tables显示信息为空,是因为还没有做统计分析。
SQL> analyze table scott.sales compute statistics;
Table analyzed.
4、重新查询dba_tables中sales表的统计信息:
SQL> select num_rows,blocks,empty_blocks from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
1382624 20197 155
5、使用delete语句删除scott用户下sales表的数据,然后提交事务。
SQL> delete scott.sales;
1382624 rows deleted.
SQL> commit;
Commit complete.
6、这次我们提前收集sales表的统计信息:
SQL> analyze table scott.sales compute statistics;
Table analyzed.
7、再次查询scott用户下的sales表所占用磁盘空间:
SQL> select blocks from dba_segments where owner='SCOTT' and segment_name='SALES';
BLOCKS
----------
20352
SQL> select num_rows,blocks,empty_blocks from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
0 20197 155
总结:此时发现scott用户下的sales表所占用的数据块依然如故没有任何改变,仍然是20532.实际上数据字典dba_segments的blocks列就是HWM,而数据字典dba_tables的blocks列与empty_blocks列之和也是HWM。
8、用直接装入的方式将dba_objects表中的全部数据插入scott用户的sales表中,并提交数据。
SQL> insert /*+ APPEND */ into scott.sales nologging select * from dba_objects;
86414 rows created.
SQL> commit;
Commit complete.
9、这次我们提前收集sales表的统计信息:
SQL> analyze table scott.sales compute statistics;
Table analyzed.
10、我们再次查询scott用户下sales表的磁盘占用情况:
SQL> select blocks from dba_segments where owner='SCOTT' where segment_name='SALES';
BLOCKS
----------
22272
1 rows selected.
SQL> select num_rows,blocks,empty_blocks from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
86414 21594 678
总结:发现delete删除了数据,并不能释放空闲块。当前的块(22271)=delete之前的块( 20352)+最后插入数据产生的数据块。
收缩段:
当一个段被收缩时,段中的数据被压缩,高水线(HWM)下移,并且磁盘空间被释放给包含此段的表空间。
段收缩分为两个阶段:
一、第一阶段:执行收缩操作。在这个阶段,Oracle尽可能地将数据行移到下方段的空闲块中并紧凑排列。
一、第二阶段:数据行移动完成以后,Oracle将启动收缩操作的第二阶段。在此阶段,将调整高水线(HWM)下移,并释放未使用空间。
实验二:收缩段实验:
1、检查sales表行迁移是否打开,发现默认是关闭状态:
SQL> select num_rows,blocks,empty_blocks,row_movement from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS ROW_MOVEMENT
---------- ---------- ------------ ----------------
86414 21594 678 DISABLED
2、打开行迁移:
SQL> alter table scott.sales enable row movement;
Table altered.
SQL> select num_rows,blocks,empty_blocks,row_movement from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS ROW_MOVEMENT
---------- ---------- ------------ ----------------
86414 21594 678 ENABLED
3、对表进行第一阶段收缩:
SQL> alter table scott.sales shrink space compact;
Table altered.
4、进行表分析,再检查磁盘使用情况:
备注:第一阶段收缩只是把行记录迁移到下方段的空闲块中,高水线并不下移,也就是占用的数据块不会改变。
SQL> analyze table scott.sales compute statistics;
Table analyzed.
SQL> select blocks from dba_segments where owner='SCOTT' and segment_name='SALES';
BLOCKS
----------
22272
SQL> select num_rows,blocks,empty_blocks,row_movement from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS ROW_MOVEMENT
---------- ---------- ------------ ----------------
86414 21594 678 ENABLED
5、对表进行第二阶段的收缩:
SQL> alter table scott.sales shrink space;
Table altered.
7、进行表分析,再检查磁盘使用情况:
备注:检查发现高水线已经从 22272个数据块下降到了1264个数据库。也可以发现第二阶段的收缩段向下调整了高水线,并释放了未使用的磁盘空间。
SQL> select blocks from dba_segments where owner='SCOTT' and segment_name='SALES';
BLOCKS
----------
1264
SQL> select num_rows,blocks,empty_blocks,row_movement from dba_tables where owner='SCOTT' and table_name='SALES';
NUM_ROWS BLOCKS EMPTY_BLOCKS ROW_MOVEMENT
---------- ---------- ------------ ----------------
86414 1234 30 ENABLED