Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2768886
  • 博文数量: 389
  • 博客积分: 4177
  • 博客等级: 上校
  • 技术积分: 4773
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-16 23:29
文章分类

全部博文(389)

分类: Oracle

2010-10-02 05:02:37

表的碎片和文件系统的碎片化的是不一样的,当随着在一个表上的DML的上
操作越来越多时,HWM之前可能有很多空闲空间,而在读取表时HWM以下的块都会被
读进来,这样会产生更多的IO,从而影响性能.只有在DDL操作才会进表的收缩,
1,建一个表,并放入一百万条记录;
create table abb (a int,c char(512));
declare
i int;
begin
for i in 1..100000 loop
insert into abb values(i,'asfsadf');
end loop;
end;
create index abb_indx on abb(a);
 
2,收集表的表信息,并查看表的空间使用情况
SQL> exec dbms_stats.gather_table_stats('SYS','ABB');
PL/SQL procedure successfully completed.
SQL> select table_name,round((blocks*8),2)/1024,round((avg_row_len*num_rows),2)/1024/1024
  2  from dba_tables
  3  where table_name='ABB';
TABLE_NAME                     ROUND((BLOCKS*8),2)/1024
------------------------------ ------------------------
ROUND((AVG_ROW_LEN*NUM_ROWS),2)/1024/1024
-----------------------------------------
ABB                                           60.109375
                               49.4003296
通过以上的结果看出,表现在大小为 60M,实际的使用空间为50M,
还有PCT为百分之十,再加上一些其他的开销,基本上实际空间和
使用的块大小相等;
3, 删除 一半的记录,这时我们发现实际的空间和HWM标记使用的块
大小相差很远了,这时候如果在读取表是会把HWM之下的块全部读
进来从而产生很多IO,结果竟然到了25M
SQL> delete from abb where a<50000;
49999 rows deleted.
exec dbms_stats.gather_table_stats('SYS','ABB');
SQL> select table_name,round((blocks*8),2)/1024,round((avg_row_len*num_rows),2)/1024/1024
  2  from dba_tables
  3  where table_name='ABB';
TABLE_NAME                     ROUND((BLOCKS*8),2)/1024
------------------------------ ------------------------
ROUND((AVG_ROW_LEN*NUM_ROWS),2)/1024/1024
-----------------------------------------
ABB                                           60.109375
                               24.7006588

4,可以通过以下办法来解决,1,使用表MOVE和索引重建,2,通过 create table XXX as select * from abb; 3,使用导出和导入表 ;在这里用MOVE的方法来解决;
SQL> alter table abb move;
Table altered.
SQL> alter index abb_indx rebuild;
Index altered.
exec dbms_stats.gather_table_stats('SYS','ABB');
SQL> select table_name,round((blocks*8),2)/1024,round((avg_row_len*num_rows),2)/1024/1024
  2  from dba_tables
  3  where table_name='ABB';
TABLE_NAME                     ROUND((BLOCKS*8),2)/1024
------------------------------ ------------------------
ROUND((AVG_ROW_LEN*NUM_ROWS),2)/1024/1024
-----------------------------------------
ABB                                          30.0546875
                               24.7006588

现在HWM以下的块的实际使用的大小基本相等,表不存在碎片;
阅读(4955) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

oracle狂热分子2014-12-29 17:41:47

high water mark

avalonzst2014-12-25 18:32:57

mark一下..弱弱的问下,HWM全称怎么写?