----- TEST1 0 0 0 0 27-SEP-14
--似乎不太准确,重新收集一下统计信息 SQL> analyze table test1 compute statistics;
Table analyzed.
--再次查看 SQL> select table_name,num_rows,blocks,empty_blocks,avg_row_len,last_analyzed from dba_tables where table_name like 'TEST%';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_ROW_LEN LAST_ANALYZED ------------------------------ ---------- ---------- ------------ ----------- ------------------ TEST1 0 0 8 0 27-SEP-14
可以看到,truncate已经把高水位降低到8了,而且是8个空块(EMPTY_BLOCKS),表示高水位以下未使用的空间,即第一个EXTENT为TEST1表分配的BLOCK空间,并且是最低值了,这与我们刚才是创建的只有表结构的空表不一样,同样是没有行数据的表,刚才创建表结构时的高水位为0。因此可以这么说,truncate降低高水位的作用也是有限的,还是剩余了1个extent的blocks的高水位,并没有完全消除。如果默认1个extent的block要大于8,那么高水位也要超过8
SQL> select header_file,header_block,bytes,blocks,extents from dba_segments where segment_name like 'TEST%';
HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS ----------- ------------ ---------- ---------- ---------- 6 130 65536 8 1
dba_segment视图也可以反映这一高水位的情况,如果对表做全表扫描,就是从130开始,扫描8个数据块,而并非之前的从130扫描到1664了
--查看剩余表空间容量 SQL> select * from dba_free_space where tablespace_name='ZLM';
TABLESPACE_NAME FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO ------------------------------ ---------- ---------- ---------- ---------- ------------ ZLM 6 136 51314688 6264 6
truncate表数据后,ZLM剩余表空间又变大了,但是要注意,又多了8个block的消耗,建表之前查看的BLOCK_ID值是128
总结:
delete删除数据会读取大量的数据块,并产生大量的redo,对数据库产生性能影响,尤其是对大表操作时,删除大量的行数据时,而truncate虽然可以有效降低高水位,但其也有一定的局限性: 1. 并不能完全消除空表的高水位,仍然会有一定的空间浪费(8K) 2. 无法用于非清空全表数据的删除的场景
|