Chinaunix首页 | 论坛 | 博客
  • 博客访问: 53474
  • 博文数量: 17
  • 博客积分: 173
  • 博客等级: 民兵
  • 技术积分: 82
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-25 19:06
文章分类
文章存档

2015年(3)

2014年(2)

2013年(4)

2012年(8)

我的朋友

分类: Oracle

2014-12-25 18:33:11

原文地址:表的碎片化 作者:oracle狂热分子

表的碎片和文件系统的碎片化的是不一样的,当随着在一个表上的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以下的块的实际使用的大小基本相等,表不存在碎片;
阅读(1247) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~