alter table move跟shrink space的區別(轉)
alter table move跟shrink space的區別
今天主要從兩點說他們的區別:
1. 碎片的整理
2.空間的收縮
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL>
建立測試表
SQL> create table test3 as
2 select rownum id,
3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,
4 trunc(sysdate) - dbms_random.value(1, 365*2) col2
5 from dual connect by rownum<=10000;
Table created
SQL> select count(1) from test3;
COUNT(1)
----------
10000
檢視錶test3的blocks使用情況:
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................40
Total Bytes.............................327680
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................31
Last Used Ext BlockId...................481921
Last Used Block.........................5
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............0
25% -- 50% free space bytes.............0
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................32
Total bytes.............................262144
PL/SQL procedure successfully completed
製造碎片
SQL> DELETE FROM TEST3 WHERE MOD(ID,3)=1;
3334 rows deleted
SQL> commit;
Commit complete
發現有碎片了
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................40
Total Bytes.............................327680
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................31
Last Used Ext BlockId...................481921
Last Used Block.........................5
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............31
25% -- 50% free space bytes.............253952
50% -- 75% free space blocks............1
50% -- 75% free space bytes.............8192
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................0
Total bytes.............................0
PL/SQL procedure successfully completed
SQL>
消除碎片
SQL> alter table test3 move;
Table altered
檢視碎片消除的效果
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................32
Total Bytes.............................262144
Unused Blocks...........................6
Unused Bytes............................49152
Last Used Ext FileId....................31
Last Used Ext BlockId...................485065
Last Used Block.........................2
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............0
25% -- 50% free space bytes.............0
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................22
Total bytes.............................180224
PL/SQL procedure successfully completed
SQL>
從以上看,碎片整理的效果很好!!!
下面在測試用shrink整理碎片
重建測試環境
SQL> drop table test3;
Table dropped
SQL>
SQL> create table test3 as
2 select rownum id,
3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,
4 trunc(sysdate) - dbms_random.value(1, 365*2) col2
5 from dual connect by rownum<=10000;
Table created
檢視test3的blocks的使用
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................40
Total Bytes.............................327680
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................31
Last Used Ext BlockId...................481921
Last Used Block.........................5
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............0
25% -- 50% free space bytes.............0
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................32
Total bytes.............................262144
PL/SQL procedure successfully completed
製造碎片
SQL> delete from test3 where mod(id,3)=1;
3334 rows deleted
SQL> commit;
Commit complete
檢視碎片情況
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................40
Total Bytes.............................327680
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................31
Last Used Ext BlockId...................481921
Last Used Block.........................5
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............31
25% -- 50% free space bytes.............253952
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................1
Total bytes.............................8192
PL/SQL procedure successfully completed
用oracle10g新功能整理碎片
SQL> alter table test3 shrink space compact cascade;
alter table test3 shrink space compact cascade
ORA-10636: ROW MOVEMENT is not enabled
SQL> alter table test3 enable row movement;
Table altered
SQL> alter table test3 shrink space compact cascade;
Table altered
再次檢視碎片的情況,發現還有一些碎片,整理碎片效果不好
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................40
Total Bytes.............................327680
Unused Blocks...........................3
Unused Bytes............................24576
Last Used Ext FileId....................31
Last Used Ext BlockId...................481921
Last Used Block.........................5
*************************************************
0% -- 25% free space blocks.............1
0% -- 25% free space bytes..............8192
25% -- 50% free space blocks............2
25% -- 50% free space bytes.............16384
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........12
75% -- 100% free space bytes............98304
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................17
Total bytes.............................139264
PL/SQL procedure successfully completed
上面是沒降低HWM,如果載降低HWM,看看效果
SQL> alter table test3 shrink space cascade;
Table altered
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................24
Total Bytes.............................196608
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................31
Last Used Ext BlockId...................481897
Last Used Block.........................8
*************************************************
0% -- 25% free space blocks.............1
0% -- 25% free space bytes..............8192
25% -- 50% free space blocks............2
25% -- 50% free space bytes.............16384
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................17
Total bytes.............................139264
PL/SQL procedure successfully completed
看來用shrink space整理碎片不徹底,再來看看move的方式
SQL> alter table test3 move;
Table altered
SQL> exec show_space_t('TEST3','auto','table','Y');
Total Blocks............................32
Total Bytes.............................262144
Unused Blocks...........................6
Unused Bytes............................49152
Last Used Ext FileId....................31
Last Used Ext BlockId...................485081
Last Used Block.........................2
*************************************************
0% -- 25% free space blocks.............0
0% -- 25% free space bytes..............0
25% -- 50% free space blocks............0
25% -- 50% free space bytes.............0
50% -- 75% free space blocks............0
50% -- 75% free space bytes.............0
75% -- 100% free space blocks...........0
75% -- 100% free space bytes............0
Unused Blocks...........................0
Unused Bytes............................0
Total Blocks............................22
Total bytes.............................180224
PL/SQL procedure successfully completed
效果很明顯,整理的很徹底
測試結論:
雖然alter table move和shrink space,都是通過物理調整rowid來整理碎片的,但shrink space整理的不徹底,他好像不是重組,而是儘可能的合併,隨意會殘留一些block無法整理
注意:
1.再用alter table table_name move時,表相關的索引會失效,所以之後還要執行 alter index index_name rebuild online; 最後重新編譯資料庫所有失效的物件
2. 在用alter table table_name shrink space cascade時,他相當於alter table table_name move和alter index index_name rebuild online. 所以只要編譯資料庫失效的物件就可以
alter table move和shrink space除了碎片整理的效果有時不一樣外,還有什麼其他的不同呢
1. Move會移動高水位,但不會釋放申請的空間,是在高水位以下(below HWM)的操作。
2. shrink space 同樣會移動高水位,但也會釋放申請的空間,是在高水位上下(below and above HWM)都有的操作。
下面通過實驗來驗證
SQL> drop table test3;
Table dropped
SQL>
SQL> create table test3 as
2 select rownum id,
3 dbms_random.string('a', round(dbms_random.value(0,10))) col1,
4 trunc(sysdate) - dbms_random.value(1, 365*2) col2
5 from dual connect by rownum<=10000;
Table created
SQL> analyze table test3 compute statistics;
Table analyzed
SQL> col segment_name for a10;
SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- ----------
TEST3 5 40
SQL> col table_name for a10;
SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST3 37 3
SQL>
從以上查詢可以看出共分了5個extents,使用了37個blocks,這37也就是test3的HWM
SQL> delete from test3 where rownum<=5000;
5000 rows deleted
SQL> commit;
Commit complete
SQL> analyze table test3 compute statistics;
Table analyzed
SQL> col segment_name for a10;
SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- ----------
TEST3 5 40
SQL> col table_name for a10;
SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST3 37 3
SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)) used_blocks from test3;
USED_BLOCKS
-----------
17
我們從查詢中可以發現test3的HWM沒有變換還是37blocks,tests總共空間為40blocks。經過刪除後test3實際用的塊是17個
下面我們用move降低下HWM
SQL> alter table test3 move;
Table altered
SQL> col segment_name for a10;
SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- ----------
TEST3 3 24
SQL> col table_name for a10;
SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST3 37 3
user_tables裡的資料沒有變化,哦,原來是忘記analyze了,從這裡也可以看出user_segments是oracle自動維護的。
SQL> analyze table test3 compute statistics;
Table analyzed
SQL> select us.segment_name,us.extents,us.blocks from user_segments us where us.segment_name=upper('test3');
SEGMENT_NA EXTENTS BLOCKS
---------- ---------- ----------
TEST3 3 24
SQL> select table_name,blocks,t.empty_blocks from user_tables t where t.table_name=upper('test3');
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST3 20 4
SQL>
現在再來看hwm變為20了,已經降下來了啊,空間也收縮了,從40blocks降到24blocks(注意收縮到initial指定值)。
但shrink space就收縮到儲存資料的最小值,下面測試說明
建立測試表:
SQL> create table test5 (id number) storage (initial 1m next 1m);
Table created
初始化資料
SQL>
SQL> begin
2 for i in 1..100000 loop
3 insert into test5 values(i);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed
SQL> analyze table test5 compute statistics;
Table analyzed
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST5';
SEGMENT_NA EXTENTS BLOCKS INIT
---------- ---------- ---------- ----------
TEST5 17 256 1
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST5 180 76
可以從查詢資料看出,test5初始化1m即128個blocks,但資料比較多,所以又按next引數要求擴充套件了1m空間,擴充套件了17個extents。
這裡的test5總空間大小為256個blocks,使用空間為180blocks,HWM也是180blocks
SQL> delete from test5 where rownum<=50000;
50000 rows deleted
SQL> analyze table test5 compute statistics;
Table analyzed
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST5';
SEGMENT_NA EXTENTS BLOCKS INIT
---------- ---------- ---------- ----------
TEST5 17 256 1
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST5 180 76
整理碎片,降低HWM
SQL> alter table test5 move;
Table altered
SQL> analyze table test5 compute statistics;
Table analyzed
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST5';
SEGMENT_NA EXTENTS BLOCKS INIT
---------- ---------- ---------- ----------
TEST5 16 128 1
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST5 85 43
從上面的查詢資料可以看出HWM已經從180降低到85,test5總大小從256blocks收縮到128個blocks(initial指定大小)。
下面看看用shrink space收縮空間的情況
SQL> alter table test5 enable row movement;
Table altered
SQL> alter table test5 shrink space;
Table altered
SQL> select SEGMENT_NAME,EXTENTS,BLOCKS,INITIAL_EXTENT/1024/1024 init from user_segments where SEGMENT_NAME='TEST5';
SEGMENT_NA EXTENTS BLOCKS INIT
---------- ---------- ---------- ----------
TEST5 11 88 1
SQL> select TABLE_NAME,BLOCKS,EMPTY_BLOCKS from user_tables where table_name='TEST5';
TABLE_NAME BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
TEST5 85 43
SQL>
從上面的資料可以看到test5進一步從128個blocks降低到88個blocks
結論:
shrink space收縮到資料儲存的最小值,alter table move(不帶引數)收縮到initial指定值,也可以用alter table test5 move storage(initial 500k)指定收縮的大小,這樣可以達到shrink space效果
經過以上測試,得出的兩個結論,到底用哪一個命令來整理碎片,消除行遷移呢?這就要根據實際業務需要,如果你只是收縮空間,資料增長很慢,那用shrink可以但是如果資料增長很快的話,用move就比較合適,避免再重新分配空間啊
備註:
在10g之後,整理碎片消除行遷移的新增功能shrink space
alter table
compact:這個引數當系統的負載比較大時可以用,不降低HWM。如果系統負載較低時,直接用alter table table_name shrink space就一步到位了
cascade:這個引數是在shrink table的時候自動級聯索引,相當於rebulid index。
普通表:
shrink必須開啟行遷移功能。
alter table table_name enable row movement ;
保持HWM,相當於把塊中資料打結實了
alter table table_name shrink space compact;
回縮表與降低HWM
alter table table_name shrink space;
回縮表與相關索引,降低HWM
alter table table_name shrink space cascade;
回縮索引與降低HWM
alter index index_name shrink space
雖然在10g中可以用shrink ,但也有些限制:
1). 對cluster,cluster table,或具有Long,lob型別列的物件 不起作用。
2). 不支援具有function-based indexes 或 bitmap join indexes的表
3). 不支援mapping 表或index-organized表。
4). 不支援compressed 表
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24104518/viewspace-764904/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- alter table move與shrink space
- [重慶思莊每日技術分享]-在為表新增了列後執行ALTER TABLE SHRINK SPACE 提示ORA-8102
- mysql的ALTER TABLE命令MySql
- Oracle move和shrink釋放高水位空間Oracle
- mysql alter modify 和 change的區別MySql
- alter table set unused column
- [20190918]shrink space與ORA-08102錯誤.txt
- create table,show tables,describe table,DROP TABLE,ALTER TABLE ,怎麼使用?
- ALTER TABLE修改列的不同方法
- alter table nologging /*+APPEND PARALLEL(n)*/APPParallel
- alter table drop unused columns checkpoint
- alter system set event和set events的區別
- MySQL-ALTER TABLE命令學習[20180503]MySql
- MySQL的create table as 與 like區別MySql
- [20191129]ALTER TABLE MINIMIZE RECORDS_PER_BLOCK.txtBloC
- 記憶體跟硬碟的區別記憶體硬碟
- Oracle 12.2之後ALTER TABLE .. MODIFY轉換非分割槽表為分割槽表Oracle
- admin_move_table線上更改分割槽鍵
- table中cesllspacing與cellpadding的區別詳解padding
- show_space(轉)
- sap table 分為三種型別(轉)型別
- MySQL中的alter table命令的基本使用方法及提速最佳化MySql
- 簡單理解 word-wrap、word-break 和 white-space 的區別
- 水平越權跟垂直越權區別?
- MySQL alter table時執行innobackupex全備再看Seconds_Behind_MasterMySqlAST
- 透過alter table 來實現重建表,同事大呼開眼界了
- 頂級高仿包跟專櫃區別
- 轉發和重定向的區別?
- word-wrap、word-break和white-space有什麼區別?
- Java中靜態跟非靜態的區別總結Java
- Android wifi上網跟4G上網的區別AndroidWiFi
- mysql表操作(alter)/mysql欄位型別MySql型別
- GLOBAL TEMPORARY TABLE(轉)
- oracle cache table(轉)Oracle
- Oracle Pipelined Table(轉)Oracle
- Linux系統好用嗎?跟Windows有何區別?LinuxWindows
- Java中HashMap,LinkedHashMap,TreeMap的區別[轉]JavaHashMap
- CSS flex-shrinkCSSFlex
- vector::shrink_to_fit()