Oracle9i下將列設為UNUSED時的系統行為

magic007發表於2008-01-19

下面以例子說話:

SQL> create table test1.unused_test  as select rownum a,rownum*2 b,rownum*10 c from dba_objects where rownum<=100;

Table created.

看看資料字典:

SQL> select column_name,data_type,column_id,hidden_column,segment_column_id seg_
cid,internal_column_id internal_cid from dba_tab_cols where wner='TEST1' and ta
ble_name='UNUSED_TEST';

COLUMN_NAM DATA_TYPE            COLUMN_ID HIDDEN    SEG_CID INTERNAL_CID
---------- -------------------- --------- ------ ---------- ------------
A          NUMBER                       1 NO              1            1
B          NUMBER                       2 NO              2            2
C          NUMBER                       3 NO              3            3

SQL> select column_name,data_type,column_id from dba_tab_columns where wner='TE
ST1' and table_name='UNUSED_TEST';

COLUMN_NAM DATA_TYPE            COLUMN_ID
---------- -------------------- ---------
A          NUMBER                       1
B          NUMBER                       2
C          NUMBER                       3

SQL> select object_id from dba_objects where wner='TEST1' and object_name='UNUS
ED_TEST' and object_type='TABLE';

 OBJECT_ID
----------
      6577

SQL> select col#,segcol#,name,intcol# from col$ where obj#=6577;

      COL#    SEGCOL# NAME          INTCOL#
---------- ---------- ---------- ----------
         1          1 A                   1
         2          2 B                   2
         3          3 C                   3

通過DUMP資料庫檔案塊可以看到每行有三列(這裡不再列出DUMP檔案內容)
下面將B列置為unused狀態:

SQL> alter table test1.unused_test set unused (b);

Table altered.

SQL> select column_name,data_type,column_id,hidden_column,segment_column_id seg_
cid,internal_column_id internal_cid from dba_tab_cols where wner='TEST1' and ta
ble_name='UNUSED_TEST';

COLUMN_NAME                  DATA_T COLUMN_ID HIDDEN    SEG_CID INTERNAL_CID
---------------------------- ------ --------- ------ ---------- ------------
A                            NUMBER         1 NO              1            1
SYS_C00002_08011915:24:34$   NUMBER           YES             2            2
C                            NUMBER         2 NO              3            3

這裡原來的B列,其名字為系統自動生成的一列,命名形式為SYS_CNNNNN_YYMMDDHH24:MI:SS$,NNNNN為原來的COLUMN_ID,前面補0補足成5數。hidden已經變為YES,COLUMN_ID為空。其他兩列A和C的COLUMN_ID順序作了調整。這三列的SEGMENT_COLUMN_ID和INTERNAL_COLUMN_ID沒有變化。

SQL> select column_name,data_type,column_id from dba_tab_columns where wner='TE
ST1' and table_name='UNUSED_TEST';

COLUMN_NAME                  DATA_T COLUMN_ID
---------------------------- ------ ---------
A                            NUMBER         1
C                            NUMBER         2

在DBA_TAB_COLUMNS檢視中,B列已經沒有顯示出來。

SQL> select col#,segcol#,name,intcol# from col$ where obj#=6577;

      COL#    SEGCOL# NAME                            INTCOL#
---------- ---------- ---------------------------- ----------
         1          1 A                                     1
         0          2 SYS_C00002_08011915:24:34$            2
         2          3 C                                     3

這裡B列的COL#已經變成0.SEGCOL#和INTCOL#列沒有變化,NAME也已經變化
DUMP出來的資料中,每一行仍然有三列。
嘗試插入資料:

SQL> insert into test1.unused_test values (1234,4321,1);
insert into test1.unused_test values (1234,4321,1)
                  *
ERROR at line 1:
ORA-00913: too many values

SQL> insert into test1.unused_test values (1234,4321);

1 row created.

SQL> select rowid from test1.unused_test where a=1234 and c=4321;

ROWID
------------------
AAABmxAAFAAAAEuAAA

此ROWID對應的rfile#為5,block#為302,row number為0
DUMP出這一塊檢視第0行資料,發現在資料塊中每行仍然是3列,第二列也就是原來的B列其值為NULL。
現在我們將C列刪除:

SQL> alter table test1.unused_test drop (c);

Table altered.

SQL> select column_name,data_type,column_id,hidden_column,segment_column_id seg_
cid,internal_column_id internal_cid from dba_tab_cols where wner='TEST1' and ta
ble_name='UNUSED_TEST';

COLUMN_NAME                  DATA_T COLUMN_ID HIDDEN    SEG_CID INTERNAL_CID
---------------------------- ------ --------- ------ ---------- ------------
A                            NUMBER         1 NO              1            1

這裡可以看出B列和C列都已經刪除。

SQL> select column_name,data_type,column_id from dba_tab_columns where wner='TE
ST1' and table_name='UNUSED_TEST';

COLUMN_NAME                  DATA_T COLUMN_ID
---------------------------- ------ ---------
A                            NUMBER         1

SQL> select col#,segcol#,name,intcol# from col$ where obj#=6577;

      COL#    SEGCOL# NAME                            INTCOL#
---------- ---------- ---------------------------- ----------
         1          1 A                                     1

都可以看出B列和C列已經被刪除。從這個實驗就可以看出,在刪除C時會將UNUSED列一併刪除。

DUMP出資料塊可以發展,塊中每一行只有1列。因此SET UNUSED只是修改了資料字典,速度較多。而將COLUMN DROP掉,不僅修改資料字典,而且修改實際的塊資料。如果表比較大,會耗費比較長的時間。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69924/viewspace-153373/,如需轉載,請註明出處,否則將追究法律責任。

相關文章