【轉】Oracle:MOVE與SHRINK命令相比較
Move命令壓縮Oracle塊中的記錄、解決行連結問題,並重置表的高水平線。
move和shrink命令都會重置表的高水平線,那麼哪個命令更有效呢?這篇文章討論使用move和shrink命令重新組織一個表,然後比較Oracle塊的記錄被壓縮得怎麼樣以及行連結解決得怎麼樣。
注意:關於表高水平線和重置表高水平線的不同方法的詳細討論不在這篇文章的討論範圍內。
下面的步驟簡要描述了使用move和shrink命令對TEMP_JP表進行重組時對該表的各種操作。在這一系列步驟中出現的一些異常被清晰地標註出來(Move相關的命令是以藍色表示,Shrink相關的命令是以綠色表示)。
01 – 03
建立表temp_jp並插入2500條記錄到這個表中。
04
顯示在表的Oracle塊中的記錄分配。
奇怪的是,插入到每個Oracle塊中的記錄數不是相同的。
05
索引表temp_jp。
06
檢驗表和索引的磁碟空間利用情況。
預設情況下,Oracle為一個表分配一個區間,為一個索引分配兩個區間。
07
對temp_jp表新增一個第三列來模擬行連結。
08
分析Temp_jp表。
09
從temp_jp表選擇行數和連結行數。
temp_jp表中幾乎所有的記錄都是連結的。
10
在模擬行連結之後檢查表和索引的磁碟空間利用情況。
表temp_jp的磁碟空間使用增加了10番。
11
刪除這個表的所有記錄,使這個表中每個Oracle塊只留一條記錄。
12
在刪除記錄之後,展開顯示temp_jp表的記錄。
記錄的數目顯示了每個Oracle塊是一致的,因為我們刪除了這個表的所有記錄,這個表中每個Oracle塊只留一條記錄。
13
分析Temp_jp表。
14
從temp_jp表選擇行數和連結行數。
15
檢查temp_jp表的索引狀態。它是VALID。
16
16-A
對錶執行move操作。
16-BA
16-BB對temp_jp表執行shrink操作。
17
17-A
在對錶執行了move操作之後,索引的狀態是不可用的。
17-B在對temp_jp表執行了操作之後,索引的狀態是無效的。
18
顯示temp_jp表和它的索引的磁碟空間使用情況。
18-A
在進行move操作之後,對錶分配了一個區間,對索引分配了兩個區間。
18-B
在進行shrink操作之後,表和索引被分配了每個具有8個Oracle塊的區間。最初分配給索引的兩個區間下降為一個。
19
展開顯示temp_jp表Oracle塊中的記錄。
19-A
在temp_jp表中的所有5條記錄被壓縮到一個Oracle塊中。
19-B
在temp_jp表中的所有5條記錄被擴充套件到3個Oracle塊中。
20
20-AA
表分析操作失敗,錯誤為ORA-01502。
20-AB
在表上重新建立索引來使其生效。
在索引重建操作之後,一個Oracle區間被分配給了這個索引。
20-AC
在索引重建之後,分析這個表。
20-B
分析這個表。
21
選擇temp_jp表的行數和行連結數。
21-A
在對temp_jp表進行move操作之後,行連結被解決了,連結行數為0。
21-B
在對temp_jp表進行shrink操作之後,行連結沒有解決。連結行數為2.
22
檢驗temp_jp表的索引狀態是有效的。
測試A
move操作怎樣影響一個表的Oracle塊中行連結和資料的分配:
01-A
drop table temp_jp;
02-A
create table temp_jp(col1 number(10),col2 varchar2(20)) tablespace users;
03-A
declare
begin
for i in 1..2500 loop
insert into temp_jp values(i,'RAMA');
end loop;
commit;
end;
/
04-A
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ -------------------------- ----------
4 2764 526
4 2765 519
4 2766 417
4 2767 519
4 2768 519
5 rows selected.
05-A
create index temp_jp_idx on temp_jp(col1) tablespace users;
06-A
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
--------------- ------------------ ---------- ---------- ----------
TEMP_JP TABLE .0625 8 1
TEMP_JP_IDX INDEX .125 16 2
07-A
alter table temp_jp add(col3 varchar2(256) default 'THIS IS TO TEST THE ROW CHAINING ISSUE
WITH MOVE COMMAND AND HOW THE DATA IS SPREAD BEFORE AND AFTER THE MOVE COMMAND IN EACH BLOCK OF THE TABLE');
08-A
analyze table temp_jp compute statistics;
09-A
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 2500 2426
10-A
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
--------------- ------------------ ---------- ---------- ----------
TEMP_JP TABLE .625 80 10
TEMP_JP_IDX INDEX .125 16 2
11-A
declare
begin
for c1 in (select DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) block,
max(rowid) max_rowid
from temp_jp group by DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)) loop
for c2 in (select rowid,DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) block
from temp_jp
where DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)=c1.block) loop
if ((c2.block = c1.block) and (c2.rowid <> c1.max_rowid)) then
delete from temp_jp where rowid = c2.rowid;
end if;
end loop;
end loop;
commit;
end;
/
12-A
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ ------------------------------------ ----------
4 2764 1
4 2765 1
4 2766 1
4 2767 1
4 2768 1
13-A
analyze table temp_jp compute statistics;
14-B
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 5 5
15-A
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
------------------------------ --------
TEMP_JP_IDX VALID
16-A
alter table temp_jp move tablespace users;
17-A
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
------------------------------ --------
TEMP_JP_IDX UNUSABLE
18-A
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
--------------- ------------------ ---------- ---------- ----------
TEMP_JP TABLE .0625 8 1
TEMP_JP_IDX INDEX .125 16 2
19-A
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ ------------------------------------ ----------
4 2908 5
20-AA
analyze table temp_jp compute statistics;
analyze table temp_jp compute statistics
*
ERROR at line 1:
ORA-01502: index 'GZBGQT.TEMP_JP_IDX' or partition of such index is in unusable state
20-AB
alter index TEMP_JP_IDX rebuild online;
20-AC
analyze table temp_jp compute statistics;
21-A
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 5 0
22-A
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
------------------------------ --------
TEMP_JP_IDX VALID
測試B
shrink操作怎樣影響一個表的Oracle塊中行連結和資料分配:
01-B
drop table temp_jp;
02-B
create table temp_jp(col1 number(10),col2 varchar2(20)) tablespace users;
03-B
declare
begin
for i in 1..2500 loop
insert into temp_jp values(i,'RAMA');
end loop;
commit;
end;
/
04-B
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ ------------------------ ----------
4 1908 526
4 1909 519
4 1910 417
4 1911 519
4 1912 519
5 rows selected.
05-B
create index temp_jp_idx on temp_jp(col1) tablespace users;
06-B
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
--------------- ------------------ ---------- ---------- ----------
TEMP_JP TABLE .0625 8 1
TEMP_JP_IDX INDEX .125 16 2
07-B
alter table temp_jp add(col3 varchar2(256) default 'THIS IS TO TEST THE ROW CHAINING ISSUE WITH MOVE
COMMAND AND HOW THE DATA IS SPREAD BEFORE AND AFTER THE MOVE COMMAND IN EACH
BLOCK OF THE TABLE');
08-B
analyze table temp_jp compute statistics;
09-B
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 2500 2426
10-B
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
--------------- ------------------ ---------- ---------- ----------
TEMP_JP TABLE .625 80 10
TEMP_JP_IDX INDEX .125 16 2
11-B
declare
begin
for c1 in (select DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) block,
max(rowid) max_rowid
from temp_jp group by DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)) loop
for c2 in (select rowid,DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) block
from temp_jp
where DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)=c1.block) loop
if ((c2.block = c1.block) and (c2.rowid <> c1.max_rowid)) then
delete from temp_jp where rowid = c2.rowid;
end if;
end loop;
end loop;
commit;
end;
/
12-B
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ -------------------------- ----------
4 1908 1
4 1909 1
4 1910 1
4 1911 1
4 1912 1
5 rows selected.
13-B
analyze table temp_jp compute statistics;
14-A
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 5 5
15-B
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
------------------------------ --------
TEMP_JP_IDX VALID
16-BA
alter table temp_jp enable row movement;
16-BB
alter table temp_jp shrink space cascade;
17-B
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
--------------------------------------
TEMP_JP_IDX VALID
18-B
select segment_name,segment_type,bytes/1024/1024 mg,blocks,extents
from user_segments where segment_name like 'TEMP%';
SEGMENT_NAME SEGMENT_TYPE MG BLOCKS EXTENTS
------------------------------------------- --------------------
TEMP_JP TABLE .0625 8 1
TEMP_JP_IDX INDEX .0625 8 1
19-B
select dbms_rowid.rowid_relative_fno(rowid) ,
dbms_rowid.rowid_block_number(rowid) ,
count(*)
from temp_jp
group by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid)
order by dbms_rowid.rowid_relative_fno(rowid),
dbms_rowid.rowid_block_number(rowid);
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) COUNT(*)
------------------------------------ -------------------------- ----------
4 1908 3
4 1909 1
4 1910 1
20-B
analyze table temp_jp compute statistics;
21-B
select table_name,num_rows,chain_cnt from user_tables where table_name='TEMP_JP';
TABLE_NAME NUM_ROWS CHAIN_CNT
------------------------------ ---------- ----------
TEMP_JP 5 2
22-B
select index_name,status from user_indexes where table_name='TEMP_JP';
INDEX_NAME STATUS
------------------------------ --------
TEMP_JP_IDX VALID
在對temp_jp表進行move操作之後,所有的記錄被壓縮排一個oracle塊中。在temp_jp表中的行連結問題被完全解決了。
shrink不能完全解決表中行連結問題。表中留下的5條記錄被擴充套件到這個表的3個oracle塊中。
在上面的比較之後,對於一個讀取要求較高、執行以毫秒來計的應用程式,我推薦使用move命令。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11411056/viewspace-733415/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [Oracle] Shrink space & Table move比較Oracle
- Oracle 11g alter table move與shrink spaceOracle
- table move 與 shrink 的區別
- 轉載-oracle Shrink命令的使用Oracle
- Oracle move和shrink釋放高水位空間Oracle
- alter table move 與shrink space的區別
- alter table move跟shrink space的區別(轉)
- ALTER TABLE MOVE | SHRINK SPACE區別
- ALTER TABLE MOVE和SHRINK SPACE區別
- Oracle中shrink space命令詳解Oracle
- Oracle中shrink space命令詳解[轉]--還示測試Oracle
- alter table move跟shrink space的區別
- alter table move 和 alter table shrink space的區別
- oracle shrinkOracle
- [轉移]ORACLE MOVE 表空間Oracle
- oracle shrink tableOracle
- 【SHRINK】Oracle收縮表的詳細命令參考Oracle
- SAP ERP 與 Oracle ERP 比較(轉)Oracle
- Oracle的move操作Oracle
- move oracle 10 directoryOracle
- Oracle 10g Shrink Table - Shrink Space 收縮空間Oracle 10g
- 與HTML相比XHTML有什麼特點?(轉)HTML
- DDD中事件與命令比較事件
- Move_or_Rename_the_Tempfile_in_OracleOracle
- ORACLE MOVE表空間Oracle
- How to Shrink Undo Segment In Oracle DatabaseOracleDatabase
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- 【轉】關於oracle中Move機制的一點探討Oracle
- (轉)ORACLE 中IN和EXISTS比較Oracle
- 獨享IP代理相比較與其他代理IP型別隱匿性會更高嗎?型別
- Oracle與SQL Server在企業應用中的比較(轉)OracleSQLServer
- Oracle 10g Shrink Table 詳解Oracle 10g
- oracle 分割槽表進行shrink操作Oracle
- oracle10g shrink space 降低HWMOracle
- 轉:Oracle常用dump命令Oracle
- 【轉】oracle基本命令Oracle
- Oracle 常用dump命令 - 轉Oracle
- Oracle常用dump命令(轉)Oracle