測試shrink space碎片整理功能:
insert into test_shrink select * from testtable; --建立30萬筆資料左右的表
select count(*) from test_shrink;
exec dbms_stats.gather_table_stats('SYS','TEST_SHRINK',CASCADE=>TRUE); --收集統計資訊
select sum(bytes)/1024/1024 from dba_segments where segment_name='TEST_SHRINK';--查看空間大小
估算高水位線(HWM)下還有多少空間可用,值越低越好,表示實際空間接近高水位線
由於用DBMS包無法分析空的blocks,所以改用analyze命令再收集一次統計資訊
analyze table TEST_SHRINK compute statistics;
SELECT blocks, empty_blocks, num_rows FROM user_tables WHERE table_name ='TEST_SHRINK';
查看高水位線下有多少空間浪費
SELECT TABLE_NAME,
(BLOCKS * 8192 / 1024 / 1024) -
(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024) "HWM下空間浪費MB"
FROM USER_TABLES
WHERE table_name = 'TEST_SHRINK';
查看全表掃描(full scan)執行計劃--消耗CPU 930
執行大量DML操作,刪除大部分的數據來查看之後空間的變化
delete from test_shrink where object_id>150;
select count(*) from test_shrink;
exec dbms_stats.gather_table_stats('SYS','TEST_SHRINK',CASCADE=>TRUE); --再次收集統計資訊
再次查看空間的浪費--浪費由5MB爆增至32MB
可見經由DML刪除操作後 高水位線並沒有下降,但空間的浪費卻非常多
再執行full scan查看執行計劃--消耗CPU 917 全表掃描依然耗費9百多的CPU,表示全掃描要掃過很多無資料的blocks
*****************************
進行shrink space碎片整理
*****************************
alter table TEST_SHRINK enable row movement; --前置作業
alter table TEST_SHRINK shrink space cascade; --shrink
select sum(bytes)/1024/1024 from dba_segments where segment_name='TEST_SHRINK';
exec dbms_stats.gather_table_stats('SYS','TEST_SHRINK',CASCADE=>TRUE); --收集統計資訊
SELECT TABLE_NAME,
(BLOCKS * 8192 / 1024 / 1024) -
(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024) "HWM下空間浪費MB"
FROM USER_TABLES
WHERE table_name = 'TEST_SHRINK';
經由shrink space 後空間的浪費減少成0.06M
因此DBA要定期執行分析統計資訊,若資料表經常使用DML操作,DBA要定期執行表空間碎片整理維護!