Oracle:alter table shrink space壓縮碎片收縮高水位
以前的技術:
對於oracle的表,資料庫在日常使用過程中,不斷的insert,delete,update操作,導致表和索引出現碎片是在所難免的事情,碎片多了,sql的執行效率自然就差了,道理很簡單,高水位線(HWL)下的許多資料塊都是無資料的,但全表掃描的時候要掃描到高水位線的資料塊,也就是說oracle要做許多的無用功!在9i的時候,一個很成熟的碎片整理技術。
alter table xxx move 高水位以下合併碎片,不移動高水位
alter table xxx move compress 高水位以下合併碎片,同時壓縮表,不移動高水位。
這個move確實整理碎片的效率很高,但是美中不足的是
1.把需要的資料放到一個臨時表,create table temp_t1 nologging Select /*+parallel(tab n)*/ * from t1 where .....
2.徹底刪了原表,drop table t1 pruge;
3.還原表,ALTER TABLE oldname temp_t1 TO t1 ;
4.重建索引,create index index_name on t1(...);
過程很複雜很耗時間。
因此oracle在10g哦時候提供了shrink space碎片整理功能,不僅能整理碎片還可以收縮高水位,索引也不需要重建。
alter table move 由於不能修改rowid(物理位置的一個id)所以無法降低高水位,而alter
table shrink space 是可以修改rowid的所以在使用之前一定要開啟行遷移:alter table OM_SERV_SUMMARY_xxxx enable row movement;
自動過程的思路:
1.先把碎片率高的表找出
select 'drop table ' || segment_name || ' purge;', sum(bytes)/1024/1024 Mbytese from user_segments a , user_tables b
where segment_type='TABLE' and a.segment_name=b.TABLE_NAME and b.COMPRESSION='DISABLED'
group by segment_name,COMPRESSION order by sum(bytes)/1024/1024 desc;
安表的空間大小排序找出來,不支援壓縮表哦。
先分析:
exec dbms_stats.gather_table_stats(user,'T1',CASCADE=>TRUE); ==這個分析很耗時間可以設定estimate_percent來調整分析的量。
如果與之前的分析時間差距太大也需要重新分析:
select table_name,last_analyzed from user_tables order by last_analyzed desc nulls last; where table_name =
'OM_SERV_SUMMARY_xxxxxx';
SELECT table_name,
ROUND((blocks * 8/1024), 2) "高水位空間 M",
ROUND((num_rows * avg_row_len / 1024/1024), 2) "真實使用空間 M",
ROUND((blocks * 10 / 100) * 8, 2) "預留空間(pctfree) M",
ROUND((blocks * 8 - (num_rows * avg_row_len / 1024) -blocks * 8 * 10 / 100), 2) "浪費空間 M",
((blocks * 8-(num_rows * avg_row_len / 1024))/1024)/(blocks * 8/1024) "浪費空間 %"
FROM user_tables
WHERE table_name = 'OM_SERV_SUMMARY_xxxxxx';
在高水位和真實使用的空間之間的差距=浪費空間,而產生浪費空間的原因是高水位的上漲,真實使用的空間變小(大量的delete)而造成的,而這樣也會產生大量的碎片。浪費空間 %大於25就需要整理了。
2.開啟行遷移
開啟之前程式需要記錄這個表原來的情況,好在壓縮完後回覆原來的模樣:
select row_movement into vc_movement from user_tables where table_name='OM_SERV_SUMMARY_xxxxx';
rowid物化檢視必須在壓縮操作之後重建所以需要開啟行遷移:
alter table OM_SERV_SUMMARY_xxxxx enable row movement;
3.進行壓縮
alter table OM_SERV_SUMMARY_xxxxx shrink space cascade;
連同索引一起壓縮,比move方便多。
再根據實際情況關閉行遷移
alter table
OM_SERV_SUMMARY_xxxxx disable row movement;
查看錶段空間下降許多
select sum(bytes)/1024/1024 from user_segments where segment_name='OM_SERV_SUMMARY_xxxxx';
不過在批量實踐當中,在分析的過程上面耗上很多的資源,所以實踐當中可以根據自己的業務邏輯來分析這一張表的碎片情況,技術和業務的結合,效率更佳。