oracle實驗記錄 (ROW 壓縮,遷移,連結)
Row Chaining &Row Migrating 定義
Row chaining:當資料第一次insert到一個塊時就無法容納,此時將發生row chaining,將放在多個塊中由指標連結(用rowid連結)
ROW migrating:當一個塊內資料 由於update更新操作導致,長度變大,原來的塊放不下了,oracle將進行row migrating,將在原來的塊中儲存一個指標,指向新的datablock(但遷移行的rowid不變,通過rowid可以查到FILE#,BLOCK#)
與之有關的建立表時的 引數 PCTFREE,PCTUSED(ASSM(auto segment space mangagement)表空間 中pctused已經廢棄,因為assm tablespace 不用 freelist管理空間,而用BITMAP,而PCTUSED主要作用就是告訴oracle什麼時候 塊要掛到freelist,沒有 freelist了 所以pctused也廢棄了,不過pctfree還有作用 還限制新行能否插入一個塊中
)
PCTFREE:指定表內每個資料塊中空間的百分比。PCTFREE 的值必須介於0 和99
之間。如果值為零,表示可以通過插入新行來填充整個塊。預設值為10。此值表示每
個塊中保留著10% 的空間,用於更新現有的行以及插入新行,每個塊最多可填充到
90%。
PCTUSED:指定為表內每個資料塊維護的已用空間的最小百分比。如果一個塊的已用
空間低於PCTUSED,則可在該塊中插入行。PCTUSED 的值為介於0 和99 之間的整
數,預設值為40。(segment management space manual時候 控制塊是否在FREELIST上),pctfree加pctused要小於100
SQL> sho user 表已建立。 SQL> insert into t1 values('a','b','c','d');~~插入大資料 已建立 1 行。 NAME TYPE VALUE SQL> select pct_free from user_tables where table_name='T1'; PCT_FREE 可以看 到default pctfree為10,塊大小為8192,還要留10%用於更新 ,塊頭資訊+行資料區資訊 應該<90%才能都放入這個塊,而實驗中每個欄位為 2000位元組,90%空間放不下資料行,將造成row chaining chained_rows表需要建立 Table created. 生成CHAINED_ROWS TABLE_NAME COUNT(*) SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;~~~另外直接用analyze也可以分析統計出來 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='T1' ; NUM_ROWS CHAIN_CNT SQL> create table t2 (a char(2000), b char(2000), c char(2000), d char(2000)) pc 表已建立。 SQL> select pct_free from user_tables where table_name='T2'; PCT_FREE SQL> insert into t2 values('a','b','c','d'); 已建立 1 行。 SQL> commit; 提交完成。 SQL> ANALYZE TABLE T2 COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='T2' ; NUM_ROWS CHAIN_CNT SQL> ANALYZE TABLE t2 LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; TABLE_NAME COUNT(*) row chaining 的解決 SQL> alter table t1 pctfree 0; 表已更改。 用10046 跟蹤move操作過程 會話已更改。 SQL> alter table t1 move; 表已更改。 WAIT #3: nam='direct path write' ela= 3 file number=4 first dba=2444 block cnt=13 obj#=0 tim=325785989 insert into seg$ (file#,block#,type#,ts#,blocks,extents,minexts,maxexts,extsize,extpct,user#,iniexts,lists,groups,cachehint,bitmapranges,hwmincr, spare1, scanhint) values ..................... SQL> alter session set events '10046 trace name context off'; 會話已更改。 SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;~~~ 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='T1' ; NUM_ROWS CHAIN_CNT 消除了row chaining~~~~另外MOVE 由於是重新insert這樣造成rowid改變所以index的失效,move還會鎖表 SQL> create table tm ( a int); 表已建立。 SQL> insert into tm values(1); 已建立 1 行。 SQL> commit; 提交完成。 SQL> create index tm_ind on tm(a); STATUS SQL> alter table TM MOVE; 表已更改。 SQL> select STATUS from user_indexes where index_name='TM_IND'; STATUS SQL> alter index tm_ind rebuild online ; 索引已更改。 SQL> 另外一種方式,row chaining出現的根本原因就是INSERT時候塊太小,所以 要建立大塊的表空間,下面是早期實驗中此類方法的解決 Table created. SQL> insert into test2 values('a','aa','aaa','aaaa','aaaaa'); 1 row created. SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS System altered. buffer tsn: 20 rdba: 0x02800022 (10/34) H-表示當前資料塊是該行的第一個塊(不一定包含該行的資料,如row migrate) SQL> ANALYZE TABLE TEST2 COMPUTE STATISTICS; Table analyzed. NUM_ROWS CHAIN_CNT SQL> @E:\oracle\product\10.1.0\Db_1\RDBMS\ADMIN\utlchain.sql; Table created. 生成CHAINED_ROWS SQL> ANALYZE TABLE test2 LIST CHAINED ROWS; 會放入 chained_rows Table analyzed. TABLE_NAME COUNT(*) NAME VALUE 查詢系統中存在 row 連結的數量 HEAD_ROWID SQL> select rowid from test2; ROWID ~2個能得到當前 連結or migrate的數量 row連結 清除 move exp/imp不管用 ~因為本身這行太長 其他塊一樣放不下,所以 只能加db_block_size清除 System altered. NAME TYPE VALUE on 32-bit Windows NT, the granule size is 8 MB for SGAs larger than 128 MB 9I Enter value for par: ksmg_granule_size NAME VALUE ISDEFAULT ISMOD IS Tablespace created. SQL> alter table xh.test2 move tablespace test_16kb; Table altered. SQL> Table analyzed. SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; no rows selected Table analyzed. SQL> select num_rows,chain_cnt from dba_tables where table_name='TEST2'; NUM_ROWS CHAIN_CNT Table truncated. SQL> ANALYZE TABLE test2 LIST CHAINED ROWS; Table analyzed. SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; no rows selected~~~~~~~~~~~~~~~~~~~~~~~~消除了 ROW migrate 表已建立。 SQL> insert into migrate(a,b) values('a','a'); 已建立 1 行。 SQL> insert into migrate(a) values('b'); 已建立 1 行。 SQL> commit; 提交完成。 SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment_ SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS SQL> select file#,block# ,rowid from (select dbms_rowid.rowid_relative_fno(rowid FILE# BLOCK# ROWID SQL> SQL> ANALYZE TABLE migrate LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; 未選定行 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE' ; NUM_ROWS CHAIN_CNT 分析 現在有2行 沒有row migrate SQL> alter system dump datafile 4 block 3685; 系統已更改。 H-FL的意思: 上邊trace檔案可以看出 2行都 存在該塊中 SQL> ANALYZE TABLE migrate LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; TABLE_NAME COUNT(*) SQL> ANALYZE TABLE MIGRATE COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE' ; NUM_ROWS CHAIN_CNT SQL> select file#,block# ,rowid from (select dbms_rowid.rowid_relative_fno(rowid FILE# BLOCK# ROWID SQL> alter system dump datafile 4 block 3685; 系統已更改。 col 1: [2000] -H-FL-- 可以看到 這行 頭和尾都在一個塊中 SQL> variable file# number; PL/SQL 過程已成功完成。 SQL> execute :blk#:=dbms_utility.data_block_address_block(to_number('1000e66',' PL/SQL 過程已成功完成。 SQL> print file# FILE# SQL> print blk# BLK# SQL> alter system dump datafile 4 block 3686; 系統已更改。 col 0: [2000] PL/SQL 過程已成功完成。 SQL> execute :blk#:=dbms_utility.data_block_address_block(to_number('1000e65',' PL/SQL 過程已成功完成。 SQL> print file# FILE# SQL> print blk# BLK# 可以看出正是 遷移前所在的位置 關於消除row migrate 有很多種方法 1.MOVE 方法 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; 未選定行 SQL> ANALYZE TABLE MIGRATE COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE' ; NUM_ROWS CHAIN_CNT 消除了 (注意move 會讓index失效,而且 LOCK表) 2.EXP/IMP 方法 表已建立。 SQL> insert into migrate2(a,b) values('a','a'); 已建立 1 行。 SQL> insert into migrate2(a) values('b'); 已建立 1 行。 SQL> commit; 提交完成。 SQL> update migrate2 set b='b',c='b' where a='b'; 已更新 1 行。 SQL> commit; 提交完成。 SQL> ANALYZE TABLE migrate2 LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; TABLE_NAME COUNT(*) SQL> ANALYZE TABLE MIGRATE2 COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE2' ; NUM_ROWS CHAIN_CNT C:\>mkdir e:\exp C:\>exp xh/a831115 file=e:\exp\migrate2.dmp tables=migrate2 Export: Release 10.2.0.1.0 - Production on 星期六 10月 24 23:58:38 2009 Copyright (c) 1982, 2005, Oracle. All rights reserved. 即將匯出指定的表通過常規路徑... SQL> truncate table migrate2; 表被截斷。 Import: Release 10.2.0.1.0 - Production on 星期日 10月 25 00:05:16 2009 Copyright (c) 1982, 2005, Oracle. All rights reserved. 經由常規路徑由 EXPORT:V10.02.01 建立的匯出檔案 SQL> ANALYZE TABLE MIGRATE2 COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE2' ; NUM_ROWS CHAIN_CNT SQL> truncate table chained_rows; 表被截斷。 SQL> ANALYZE TABLE migrate LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; 未選定行 SQL> 3.CTAS 方式 CREATE TABLE table_name_temp AS SELECT * FROM table_name WHERE rowid IN(SELECT head_rowid FROM chained_rows WHERE table_name = 'table_name'); 表已建立。 SQL> insert into migrate3(a,b) values('a','a'); 已建立 1 行。 SQL> insert into migrate3(a) values('b'); 已建立 1 行。 SQL> commit; 提交完成。 SQL> update migrate3 set b='b',c='b' where a='b'; 已更新 1 行。 SQL> commit; 提交完成。 SQL> ANALYZE TABLE migrate3 LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; TABLE_NAME COUNT(*) SQL> ANALYZE TABLE MIGRATE3 COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE3' ; NUM_ROWS CHAIN_CNT SQL> create table migrate3_test as select * from migrate3 where rowid in (select 表已建立。 SQL> delete migrate3 where rowid in (select head_rowid from chained_rows where t 已刪除 1 行。 SQL> commit; 提交完成。 SQL> insert into migrate3 select * from MIGRATE3_TEST; 已建立 1 行。 SQL> commit 提交完成。 表已刪除。 SQL> ANALYZE TABLE MIGRATE3 COMPUTE STATISTICS; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='MIGRATE3' ; NUM_ROWS CHAIN_CNT SQL> TRUNCATE TABLE CHAINED_ROWS ; 表被截斷。 SQL> ANALYZE TABLE migrate3 LIST CHAINED ROWS; 表已分析。 SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name; 未選定行 消除了 關於表壓縮 oracle compress SQL> create table cm (a char(20),b char(20)); 表已建立。 1 declare PL/SQL 過程已成功完成。 SQL> SQL> select count(distinct a) from cm; COUNT(DISTINCTA) SQL> select count(distinct b) from cm; COUNT(DISTINCTB) SQL> SEGMENT_NA FILE_ID BLOCK_ID BLOCKS SQL> select file_id,block_id,blocks from dba_extents where segment_name='CM'; FILE_ID BLOCK_ID BLOCKS SQL> select distinct block# from (select dbms_rowid.rowid_relative_fno(rowid) f BLOCK# BLOCK# 已選擇13行。 SQL> 表已更改。 SEGMENT_NA FILE_ID BLOCK_ID BLOCKS SQL> select file_id,block_id,blocks from dba_extents where segment_name='CM'; FILE_ID BLOCK_ID BLOCKS SQL> select distinct block# from (select dbms_rowid.rowid_relative_fno(rowid) f BLOCK# 已選擇8行。 系統已更改。 data_block_dump,data header at 0x80c227c tab 1, row 0, @0x1f4e tab 1, row 714, @0x115c 關於compress與 row migrate 如果執行UPDATE 將造成row migrate 表變大. 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='CM' ; NUM_ROWS CHAIN_CNT 已更新2000行。 SQL> commit; 提交完成。 SQL> analyze table cm compute statistics; 表已分析。 SQL> select num_rows,chain_cnt from dba_tables where table_name='CM' ; NUM_ROWS CHAIN_CNT 一個update操作產生大量row migrate 系統已更改。 tl: 9 fb: --H----- lb: 0x2 cc: 0 SEGMENT_NA FILE_ID BLOCK_ID BLOCKS
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12020513/viewspace-611339/,如需轉載,請註明出處,否則將追究法律責任。
小結:總得來說PCTFREE 就是告訴ORACLE 什麼時候把BLOCK從FREELIST拿走(自動段空間管理沒有FREELIST)拿走後,當空閒空間=pctfree時候 將不允許插入新資料,然後隨著使用即使以後的空閒空間>PCTFREE 塊也不掛到FREELIST(使用空間<90%時),只有當已使用空間
由於是1OGR2 預設表空間都是ASSM 簡單實驗下pctfree對row chaining的影響
USER 為 "XH"
SQL>
SQL> create table t1 (a char(2000), b char(2000), c char(2000), d char(2000));建立一個表
SQL> show parameter block_size
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
----------
10
SQL> ANALYZE TABLE t1 LIST CHAINED ROWS;oracle分析表 如果有row chaining or row migrate 那麼將會放入chained_rows這個表
表已分析。
指令碼 位置 :RDBMS\ADMIN\utlchain.sql;
create table CHAINED_ROWS (
owner_name varchar2(30),
table_name varchar2(30),
cluster_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
head_rowid rowid,
analyze_timestamp date
);
SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name;
------------------------------ ----------
T1 1~~~~看到有一個row chaining
---------- ----------
1 1~~~~~~~~~~~~~~~~~~~~~~~~~
tfree 0;
----------
0
建立另外一個表 T2 PCTFREE設定為0 沒有留update空間,行資料區+塊頭資訊 可以使用塊的100%空間
---------- ----------
1 0~~~~~~~~~~沒有產生row chainging
------------------------------ ----------
T1 1~~~~~~~~~~沒有表T2的資訊
降低PCT FREE
看 到內部相當於 一個 ctas操作
SQL> alter session set events '10046 trace name context forever,level 12';
trace中 摘錄內容:
WAIT #3: nam='direct path write' ela= 49 file number=4 first dba=2444 block cnt=13 obj#=0 tim=325786033
WAIT #3: nam='direct path write' ela= 2 file number=4 first dba=2458 block cnt=5 obj#=0 tim=325786070
WAIT #3: nam='direct path write' ela= 3 file number=4 first dba=2458 block cnt=5 obj#=0 tim=325786418
WAIT #3: nam='direct path write' ela= 59 file number=4 first dba=2458 block cnt=5 obj#=0 tim=325786474
看到大量的 直接路徑插入 實驗 表
更新資料字典操作
delete from seg$ where ts#=:1 and file#=:2 and block#=:3
---------- ----------
1 0
SQL> select STATUS from user_indexes where index_name='TM_IND';
--------
VALID~~~~~~~~~~~~INDEX 失效
--------
UNUSABLE
SQL> create table test2(a char(2000),b char(2000),c char(2000),d char(2000),e ch
ar(2000)) tablespace test;
commit;
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment_
name='TEST2' and wner='XH';
-------------------- ---------- ---------- ----------
TEST2 10 33 8
SQL> alter system dump datafile 10 block min 34 block max 42;
轉儲一下資料塊的結構
block_row_dump:
tab 0, row 0, @0x69
tl: 7967 fb: -----LP- lb: 0x1 cc: 4(4列)
col 0: [1952]
........................
buffer tsn: 20 rdba: 0x02800023 (10/35)
tab 0, row 0, @0x1793
tl: 2061 fb: --H-F--N lb: 0x1 cc: 2(2列)
nrid: 0x02800022.0***** 用rowid連線
col 0: [2000]
~~~~~~~~~~~~~~~~~~~~~~~~~~6列分到2個block中
F-表示該行資料的第一個片斷
L-表示改行的最後一個片斷
FL-表示改行的資料都在該資料快中.
N-表示該行在當前這個資料塊中的最後一列沒有結束,其餘的資料存放在由rowid指向的下一個資料塊中 (next表示這一行連線到下一行)。
P-表示該行在當前這個資料塊中的第一列是從別的塊延續過來的。
PN-會出現在行chained的地方,如果一行的資料超過一個塊時就會出現
計算下row migregate or row連結數量
SQL> select num_rows,chain_cnt from dba_tables where table_name='TEST2' ;
---------- ----------
1 1 ~~~~~~有一個行連結
create table CHAINED_ROWS (
owner_name varchar2(30),
table_name varchar2(30),
cluster_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
head_rowid rowid,~~*************************
analyze_timestamp date
);
SQL> SELECT table_name, count(*) from chained_rows GROUP BY table_name;
------------------------------ ----------
TEST2 1
SQL> SELECT name, value FROM v$sysstat WHERE name = 'table fetch continued row'
2 ;
---------------------------------------------------------------- ----------
table fetch continued row 164
SQL> SELECT head_rowid from chained_rows;~
------------------
AAANORAAKAAAAAjAAA
------------------
AAANORAAKAAAAAjAAA
SQL> alter system set db_16k_cache_size=2m;
SQL> show parameter db_16
------------------------------------ ----------- ------------------------------
db_16k_cache_size big integer 8M ~~~~~granule
on 32-bit Windows, the granule size is 8 M for SGAs larger than 1 GB. 10G
受 _ksmg_granule_size控制
old 14: x.ksppinm like '%_&par%'
new 14: x.ksppinm like '%_ksmg_granule_size%'
ADJ
------------------------------ ------------------------- --------- ---------- --
---
KSPPDESC
--------------------------------------------------------------------------------
----------------------------------------------------
_ksmg_granule_size 4194304 TRUE FALSE FA
LSE
granule size in bytes
SQL> create tablespace test_16KB datafile 'd:\test_16KB.dbf' size 10m blocksize
16k;
SQL> ANALYZE TABLE test2 LIST CHAINED ROWS;
SQL> ANALYZE TABLE TEST2 COMPUTE STATISTICS;
---------- ----------
1 0****************************
SQL> truncate table chained_rows;
SQL> create table migrate (a char(2000), b char(2000),c char(2000));
name='MIGRATE' and wner='XH';
------------------------------ ---------- ---------- ----------
MIGRATE 4 3681 8
) file#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from MIGRATE);
---------- ---------- ------------------
4 3685 AAANSQAAEAAAA5lAAA
4 3685 AAANSQAAEAAAA5lAAB
SQL> ANALYZE TABLE MIGRATE COMPUTE STATISTICS;
---------- ----------
2 0
data_block_dump,data header at 0x8062264
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x08062264
bdba: 0x01000e65
76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x819
avsp=0x803
tosp=0x803
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0xfef
0x14:pri[1] offs=0x819
block_row_dump:
tab 0, row 0, @0xfef
tl: 4009 fb: --H-FL-- lb: 0x1 cc: 2 (第1行中2列)
col 0: [2000]
61 20 20 20 20 20 20 2~~~~~~~~~~~~~~~值A
col 1: [2000]
61 20 20 20 ~~~~~~~~~~~~~~~~~~~~~~~~值A
tl: 2006 fb: --H-FL-- lb: 0x1 cc: 1(第2行中2列)
col 0: [2000]
62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 ~~~~~~~~~~~~~~~~~~~~~~~值B
H-表示當前資料塊是該行的第一個塊
FL-表示改行的資料都在該資料快中
------------------------------ ----------
MIGRATE 1
---------- ----------
2 1
) file#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from MIGRATE);
---------- ---------- ------------------
4 3685 AAANSQAAEAAAA5lAAA
4 3685 AAANSQAAEAAAA5lAAB~~~rowid沒變
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x819
avsp=0x803
tosp=0xfd0
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0xfef
0x14:pri[1] offs=0x819
block_row_dump:
tab 0, row 0, @0xfef
tl: 4009 fb: --H-FL-- lb: 0x0 cc: 2(2列)
col 0: [2000]
61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20
61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 2
tl: 9 fb: --H----- lb: 0x2 cc: 0~~~~~~~(0列 原來的 資料遷移了)
nrid: 0x01000e66.0~~~指標指向遷移的block,ROWID不變,可以從H 看出來 表示當前資料塊是該行的第一個塊(不一定包含該行的資料,如row migrate)
end_of_block_dump
通過NRID 找到 遷移行所在的block
SQL> variable blk# number;
SQL> execute :file#:=dbms_utility.data_block_address_file(to_number('1000e66','x
xxxxxx'));
xxxxxxx'));
----------
4
----------
3686
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x7fe
avsp=0x7ea
tosp=0x7ea
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x7fe
block_row_dump:
tab 0, row 0, @0x7fe
tl: 6018 fb: ----FL-- lb: 0x1 cc: 3(3列)
hrid: 0x01000e65.1*****這個HRID 也是一個指標 指向原來遷移的位置的塊
62 20 20 20 ~~~~值B
col 1: [2000]
62 20 20 20~~~~值B
col 2: [2000]
62 20 20 20~~~~值B
通過hrid找到原來遷移前所在的block
SQL> variable blk# number;
SQL> variable file# number;
SQL> execute :file#:=dbms_utility.data_block_address_file(to_number('1000e65','x
xxxxxx'));
xxxxxxx'));
----------
4
----------
3685
SQL> ANALYZE TABLE migrate LIST CHAINED ROWS;
---------- ----------
2 0
SQL> create table migrate2 (a char(2000), b char(2000),c char(2000));
------------------------------ ----------
MIGRATE2 1
---------- ----------
2 1
連線到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已匯出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集
. . 正在匯出表 MIGRATE2匯出了 2 行
成功終止匯出, 沒有出現警告。
C:\>imp xh/a831115 file=e:\exp\migrate2.dmp tables=migrate2 ignore=y
連線到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已經完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的匯入
. 正在將 XH 的物件匯入到 XH
. 正在將 XH 的物件匯入到 XH
. . 正在匯入表 "MIGRATE2"匯入了 2 行
成功終止匯入, 沒有出現警告。
---------- ----------
2 0
消除了
DELETE table_name WHERE rowid IN(SELECT head_rowidFROM chained_rowsWHERE table_name = 'table_name');
INSERT INTO table_name SELECT * FROM table_name_temp;DROP TABLE table_name_temp;
很簡單ctas重新建立一個表(直接載入寫入)
將遷移行 複製到 新表中
從原始表刪除遷移行
將行從新表複製到原表中
SQL> create table migrate3 (a char(2000), b char(2000),c char(2000));
------------------------------ ----------
MIGRATE3 1
---------- ----------
2 1
head_rowid from chained_rows where table_name='MIGRATE3');
able_name='MIGRATE3');
2 ;
SQL> drop TABLE MIGRATE3_TEST;
---------- ----------
2 0
可以壓縮資料塊內重複的值,重複值存在符號表(塊頭),原來位置存一個指標指向符號表
SQL> ed
已寫入 file afiedt.buf
2 begin
3 for i in 1..1000 loop
4 insert into cm values('a','b');
5 end loop;
6 for i in 1..1000 loop
7 insert into cm values('a'||i,'b'||i);
8 end loop;
9 commit;
10* end;
11 /
----------------
1001
----------------
1001
可以 看到這個表a,b列有1001個不同值
SQL> col segment_name format a10
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment
_name='CM';
---------- ---------- ---------- ----------
CM 4 2329 8
CM 4 2353 8
---------- ---------- ----------
4 2329 8
4 2353 8
ile#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from CM);
----------
2333
2353
2354
2357
2358
2359
2332
2334
2335
2336
2355
----------
2356
2360
SQL> alter table xh.cm move compress;
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment
_name='CM';
---------- ---------- ---------- ----------
CM 4 2361 8
CM 4 2369 8
---------- ---------- ----------
4 2361 8
4 2369 8
ile#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from CM);
----------
2364
2367
2368
2369
2371
2365
2366
2370
~~~~~~~~~~~~~~~~可以看到使用的 塊減少了(13減少為8)
轉儲結構看下
SQL> alter system dump datafile 4 block 2364;
===============
tsiz: 0x1f80 (total data area size)
hsiz: 0x5bc (data header size=(14+ntabs*4 + nrows*2)
pbl: 0x080c227c (pointer to buffer holding the block)
bdba: 0x0100093c (block dba ,rdba)
76543210
flag=-0------(O表示 compress , n=pctfree hit (clusters),f=don't put on freelist, k=flushable cluster keys)
ntab=2 (表示塊中含有2個表資訊,有一個就是symbol table,cluster時候也>1)
nrow=716 (number of rows)~~~可以看到如果是正常表,這個塊是存不了 這麼多行應該在200ROW左右
frre=-1
fsbo=0x5bc (free space begin offset)
fseo=0x115c (free space end offset)
avsp=0x74 (available space in the block)
tosp=0x74(total available space when all transactions commit)
r0_9ir2=0x0
mec_kdbh9ir2=0x1
76543210
shcf_kdbh9ir2=----------
76543210
flag_9ir2=--R----C
fcls_9ir2[3]={ 0 32768 32768 }
0x1c:pti[0] nrow=1 offs=0 (symbol表裡有一條記錄(a,b)存compress後的值)
0x20:pti[1] nrow=715 offs=1 這個block中其餘 715條是重複記錄只存指向symbol的指標
0x24:pri[0] offs=0x1f53
0x26:pri[1] offs=0x1f4e
0x28:pri[2] offs=0x1f49
''''''''''''''''''''''''''''''
0x5ba:pri[715] offs=0x115c
block_row_dump:
tab 0, row 0, @0x1f53 (tab 0 就是符號表)
tl: 45 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [20] 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 值 A
col 1: [20] 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 值 B
bindmp: 02 cb 02 dc 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 dc 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
tl: 5 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [20] 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20~~~值A
col 1: [20] 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20~~~值B
bindmp: 2c 00 01 02 00 (02 表示compress 2個欄位)
.................................
tl: 5 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [20] 61 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
col 1: [20] 62 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
bindmp: 2c 00 01 02 00~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~指標指向符號表,儲存的實際值,就是這樣大量的指標指向符號表
SQL> analyze table cm compute statistics;
---------- ----------
2000 0
SQL> update cm set b='c';
---------- ----------
2000 844
SQL> alter system dump datafile 4 block 2364;
nrid: 0x01000944.0~~~~~~~~~~~~~~~~~~~~~~~~~~~~ROW migrate 指向遷移到的block
bindmp: 20 02 00 01 00 09 44 00 00
tab 1, row 3, @0x1ee5
tl: 9 fb: --H----- lb: 0x2 cc: 0
nrid: 0x01000944.1
bindmp: 20 02 00 01 00 09 44 00 01
tab 1, row 4, @0x1edc
tl: 9 fb: --H----- lb: 0x2 cc: 0
nrid: 0x01000944.2
SQL> col segment_name format a10
SQL> select segment_name,file_id,block_id,blocks from dba_extents where segment_
name='CM';
---------- ---------- ---------- ----------
CM 4 2361 8
CM 4 2369 8
CM 4 2409 8~~~~~~~~~~~~可以看到表變大了(原來是2個區,現在3個區)
相關文章
- Row Migration and Row Chaining(行遷移和行連結)AI
- 行連結(Row chaining)和行遷移(Row Migration)的讀書筆記AI筆記
- 【轉載】行遷移和行連結(row chaining or row migration)AI
- Oracle行遷移實驗Oracle
- oracle實驗記錄 (移動outlines)Oracle
- 【實驗】【索引壓縮】索引壓縮演示及優缺點總結索引
- 實驗:行遷移與分析語句 row migration and analyze statements
- 模擬Oracle行遷移和行連結Oracle
- Oracle遷移資料庫過程記錄Oracle資料庫
- oracle實驗記錄 (flashback)Oracle
- oracle實驗記錄 (OMF)Oracle
- oracle實驗記錄 (NET)Oracle
- oracle實驗記錄 (audit)Oracle
- 選出有行連線(row chain)或者是行遷移(row migeration)的表AI
- APK體積壓縮整理記錄APK
- oracle實驗記錄 (oracle reset parameter)Oracle
- oracle compress壓縮小記Oracle
- 行遷移和行連結
- Oracle 行遷移 & 行連結的檢測與消除Oracle
- oracle遷移資料經驗Oracle
- Oracle Data Redaction實驗記錄Oracle
- oracle實驗記錄 (block cleanout)OracleBloC
- oracle實驗記錄 (dump undo)Oracle
- oracle實驗記錄 (inlist card)Oracle
- Oracle Job 遷移小記Oracle
- oracle實驗記錄 (oracle 資料字典)Oracle
- oracle實驗記錄 (連線選擇率,範圍與null)OracleNull
- ORACLE 壓縮Oracle
- Oracle資料庫中資料行遷移與行連結Oracle資料庫
- Oracle中行遷移和行連結的清除及檢測Oracle
- 清除行遷移和行連結
- 連載一:Oracle遷移文件大全Oracle
- 連載二:Oracle遷移文章大全Oracle
- Oracle檔案改名實驗記錄Oracle
- oracle實驗記錄 (選擇率)Oracle
- oracle實驗記錄 (dump logfile)Oracle
- oracle實驗記錄 (事務控制)Oracle
- oracle實驗記錄 (函式index)Oracle函式Index