表收缩和表压缩,收缩和碎片整理一个概念

高水位线

HWM是一个标记,用来说明已经有多少数据块分配给这个segmentDBA_TABLES.BLOCKSHWMHWM通常增长的幅度为一次5个数据块,原则上HWM只会增大,不会缩小,即使将表中的数据全部删除,HWM还是为原值,由于这个特点,使HWM很象一个水库的历史最高水位,这也就是HWM的原始含义,当然不能说一个水库没水了,就说该水库的历史最高水位为0。但是如果我们在表上使用了truncate命令,则该表的HWM会被重新置为0

a) 全表扫描通常要读出直到HWM标记的所有的属于该表数据库块,即使该表中没有任何数据。

b) 即使HWM以下有空闲的数据库块,键入在插入数据时使用了append关键字,则在插入时使用HWM以上的数据块,此时HWM会自动增大。如果插入数据时没有append关键字,则插入时会在HWM以内找空闲的块,这样HWM就不会增大

高水位线内的块分4种,一种是满了的块,一种没满的块,一种是extents扩展的空块,一种是删除数据后的空块

 

DBA_SEGMENTS.BLOCKS=DBA_TABLES.BLOCKS+ DBA_TABLES.EMPTY_BLOCKS

DBA_TABLES.EMPTY_BLOCKS 代表分配给该表,但是在高水位线以上的数据库块。因为每一次对表进行拓展都是以extent为单位的,所以会出现空数据块。

Delete操作的时候,dba_segments.Blocksuser\dba_tables.Blocks user\dba_tables.empty_blocks三者都不会减小

 

insert /*+append*/ into XXX values(XXX);

使用append提示进行insert时系统不去查找freelist链表中的空闲块,直接在高水标记位以上插入数据,因此速度比较快。但若是对于经常delete的表,浪费磁盘空间太大。

 

查找数据库中实际大小和分配的空间差别最大的表,查找脚本如下:

条件为什么block>100,因为一些很小的表,只有几行数据实际大小很小,但是block一次性分配就是5个,5block相对于几行小表数据来说就相差太大了

算法中/0.9是因为块的pfree一般为10%,所以一个块最多只用了90%,而且一行数据大于8KB时容易产生行链接,把一行分片存储,一样的一个块连90%都用不满

AVG_ROW_LEN还是比较准的,比如个人实验情况一表6个字段,一个number,其他5个都是char(100)但是实际数据都是’1111111’7位,AVG_ROW_LEN显示依然为513

可收缩的空间本人习惯称呼它们为碎片

SELECT TABLE_NAME,(BLOCKS*8192/1024/1024)"理论大小M",

(NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)"实际大小M",

round((NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024),3)*100||'%' "实际使用率%"

FROM USER_TABLES where blocks>100 and (NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024)<0.3

order by (NUM_ROWS*AVG_ROW_LEN/1024/1024/0.9)/(BLOCKS*8192/1024/1024) desc

 

 

 

个人一般推荐alter table tablename movealter index indexname rebuild不带online;系统不忙的话推荐alter table shrink space cascade;

实践中需要收缩表的情况:张超大的表,你删除了80%以上的数据,就算立即收集了统计信息这张表的segments不变,该表对应的dba_data_files.file_name,dba_free_space.free大小不变,感觉dba_free_space.free虽然看起来不足,但是你仍可以继续insert 80%的数据到这张表,新增80%数据过程中segments、dba_data_files.file_name、dba_free_space.free还是不变
因为空块可以重用
当然,只有执行了表收缩,表的segments才能降下来,该表对应的dba_free_space.free会增加,dba_data_files.file_name占用的空间降低。
所以碎片其实就是空块和半空块。

实践中发现表收缩会产生很多REDO、UNDO、archvied log,比如执行alter table shrink space cascade

 

 

表收缩的方法

1.  alter table tablename move [tablespace tablespacename]

1.1如果不指定表空间,就是在原表空间上move.需要额外一倍表大小空间,

1.2索引会失效,需要rebuild一下。

1.3不能在线进行,如果先执行dm操作没有commit,后再move则会直接报错;如果先move操作,期间可以执行select和平时一样正常速度返回数据,执行其他dml的话非常慢一直在等待move完成了才会真正开始执行。

 

2.  alter table shrink space [ | compact | cascade ];

1.1必须开启行迁移功能(rowid 要发生变化)alter table table_name enable row movement; 注意:alter table XXX enable row movement语句会造成引用表XXX的对象(如存储过程、包、视图等)变为无效。执行完成后,最好执行一下utlrp.sql来编译无效的对象。

1.2表空间是auto管理方式

1.3不需要额外的空间

1.4可以在线进行,不管dml在前还是在后,也不管有没有commit shrink也会正常执行完毕

1.5整理后,索引有效

 

alter table shrink space compcat;

收缩表,相当于把块中数据打结实了,但会保持 high water mark;

当系统的负载比较大时可以用

alter table shrink space;

收缩表,降低 high water mark;

alter table shrink space cascade;

收缩表,降低 high water mark,并且相关索引也会收缩一下,相当于rebulid index online

 

3.  Truncate

 

4.  expdp\impdp重新导出导入

 

 

 

表压缩和索引压缩

表压缩其实就是把表中重复的数据去掉,采用算法来替代这样重复的值

索引压缩其实就是把索引中重复的索引值去掉(表的字段值一样代表索引值一样,但是B树索引并不是说索引值后面对一大堆的rowid,而是一个索引值对应一个rowid,索引值是一样,但是rowid并不一样,索引索引块里面有很多记录行比如如下),采用算法来替代这样重复的值

索引值 rowid

5        1

5        8

5        13

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30126024/viewspace-2120235/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30126024/viewspace-2120235/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值