您的位置:首页 > 其它

set unused column column_name 和…

2017-05-02 10:48 288 查看
 
http://hi.baidu.com/dba_jungle/blog/item/e0e0fa3ed39db00dbaa1671d.html  
要删除表中不用的字段,如果直接drop
column,对于大表,进行DDL操作的时间会比较长,会严重阻塞DML语句,导致应用服务器crash,通常的做法是先set
unused column column_name 或者 set unused
column_name,column_name...,然后再利用停机时间做alter table table_name drop
unused columns。
set unused column是对列进行逻辑删除,而drop
column是对列进行物理删除,它们的共同点是对列进行删除,使用set unused
column删除列更快一些,逻辑删除好处就是可以当资源紧张的时候,节约处理时间,当以后空余的时间再真正DROP掉。

SQL>  select * from test
where rownum<10;

NICK                        
ID

-------------------- ----------

zhaolin1346                  
3

zhaolin1347                  
3

zhaolin1348                  
3

zhaolin1349                  
3

zhaolin1350                  
3

zhaolin1351                  
3

zhaolin1352                  
3

zhaolin1353                  
3

zhaolin1354                  
3

9 rows selected.

SQL> create
index idx_test_id on test(id);

Index created.

SQL> select
index_name,table_name from user_indexes where
table_name='TEST';

INDEX_NAME                    
TABLE_NAME

------------------------------ ------------------------------

IDX_TEST_NICK                 
TEST

IDX_TEST_ID                   
TEST

SQL> ALTER
TABLE TEST SET UNUSED COLUMN ID;

Table altered.

SQL>  select
index_name,table_name from user_indexes where
table_name='TEST';

INDEX_NAME                    
TABLE_NAME

------------------------------ ------------------------------

IDX_TEST_NICK                 
TEST

SQL> desc
test;

Name                                     
Null?   
Type

----------------------------------------- --------
----------------------------

NICK                                              
VARCHAR2(20)

SQL> alter
table test drop unused columns;

Table altered.

SQL> desc
test;

Name                                     
Null?   
Type

----------------------------------------- --------
----------------------------

NICK               
4000
                               
VARCHAR2(20)

另外,set unused column
column_name包含此列的索引也会被drop掉

 

--下面的附加实验是验证在set unused column
之后,在下次插入新的记录时,会不会再为此column分配存储空间

SQL> select
rowid,t.* from test t;

ROWID             
NICK                        
ID

------------------ -------------------- ----------

AAAB6sAAFAAAAAuAAA
zhaolin                     
10

SQL>
select dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,

2        
dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block# from
test;


    
FILE#    
BLOCK#

---------- ----------

5        
46

SQL> alter system dump datafile 5 block
46;


System altered.

--以下是dump文件的信息

data_block_dump,data header at 0x5374464

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x05374464

bdba: 0x0140002e

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f8a

avsp=0x1f76

tosp=0x1f76

0xe:pti[0] nrow=1 offs=0

0x12:pri[0] offs=0x1f8a

block_row_dump:

tab 0, row 0, @0x1f8a

tl: 14 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 7]  7a 68 61 6f 6c 69
6e
col  1: [
2]  c1 0b
end_of_block_dump

End dump data blocks tsn: 7 file#: 5 minblk 46 maxblk 46

--在set
unused column
id之后,对于新插入的记录,id列会不会不用再分配存储空间了
SQL>
alter table test set unused column id;

Table altered.

SQL> insert
into test(nick) values('nature');

1 row created.

SQL>
commit;

Commit complete.

SQL> select
dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,

2        
dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block# from
test;

    
FILE#    
BLOCK#

---------- ----------

5        
46

5        
46

SQL> alter
system dump datafile 5 block 46;

System altered.

SQL> select *
from test;

NICK

--------------------

zhaolin

nature

--以下是dump文件的信息

data_block_dump,data header at 0x5374464

===============

tsiz: 0x1f98

hsiz: 0x16

pbl: 0x05374464

bdba: 0x0140002e

76543210

flag=--------

ntab=1

nrow=2

frre=-1

fsbo=0x16

fseo=0x1f7f

avsp=0x1f69

tosp=0x1f69

0xe:pti[0] nrow=2 offs=0

0x12:pri[0] offs=0x1f8a

0x14:pri[1] offs=0x1f7f

block_row_dump:

tab 0, row 0, @0x1f8a

tl: 14 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 7]  7a 68 61 6f 6c 69
6e
col  1: [
2]  c1 0b --原来的空间并不会释放
tab 0, row 1,
@0x1f7f

tl: 11 fb: --H-FL-- lb: 0x2  cc: 2

col  0: [ 6]  6e 61 74 75 72
65
col  1: [0]
--从这里可以看出,不会再分配存储空间了,但是保留着列的标识符
end_of_block_dump

End dump data blocks tsn: 7 file#: 5 minblk 46 maxblk 46

我们新增加列是定长型的列address
char(10)
SQL> alter table test
add(address char(10));

Table altered.

SQL> select
dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,

2        
dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block# from
test;

    
FILE#    
BLOCK#

---------- ----------

5        
46

5        
46

SQL>  alter system dump
datafile 5 block 46;

System altered.

SQL> desc
test;

Name                                     
Null?   
Type

----------------------------------------- --------
----------------------------

NICK                                              
VARCHAR2(20)

ADDRESS                                           
CHAR(10)

SQL> insert
into test values('cat','china hang');

1 row created.

SQL>
commit;

Commit complete.

SQL>  alter system dump
datafile 5 block 46;

System altered.

SQL>  select
dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,

2         
dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block# from
test;

    
FILE#    
BLOCK#

---------- ----------

5        
46

5        
46

5        
46

--dump文件如下

data_block_dump,data header at 0x5374464

===============

tsiz: 0x1f98

hsiz: 0x1a

pbl: 0x05374464

bdba: 0x0140002e

76543210

flag=--------

ntab=1

nrow=4

frre=-1

fsbo=0x1a

fseo=0x1f62

avsp=0x1f48

tosp=0x1f48

0xe:pti[0] nrow=4 offs=0

0x12:pri[0] offs=0x1f8a

0x14:pri[1] offs=0x1f7f

0x16:pri[2] offs=0x1f6c

0x18:pri[3] offs=0x1f62

block_row_dump:

tab 0, row 0, @0x1f8a

tl: 14 fb: --H-FL-- lb: 0x0  cc: 2

col  0: [ 7]  7a 68 61 6f 6c 69
6e

col  1: [ 2]  c1 0b

tab 0, row 1, @0x1f7f

tl: 11 fb: --H-FL-- lb: 0x0  cc: 2

col  0: [ 6]  6e 61 74 75 72
65

col  1: [0]

tab 0, row 2, @0x1f6c

tl: 19 fb: --H-FL-- lb: 0x1  cc: 3

col  0: [ 3]  63 61 74

col  1: [0]
col  2:
[10]  63 68 69 6e 61 20 68 61 6e 67

tab 0, row 3, @0x1f62

tl: 10 fb: --H-FL-- lb: 0x2  cc: 3

col  0: [ 4]  6c 61 73 74

col  1: [0]
col  2: [0]
--从这里可以看出,不会再分配存储空间了

end_of_block_dump

End dump data blocks tsn: 7 file#: 5 minblk 46 maxblk 46

所以在set unused
column之后,不会再为新插入的记录分配存储空间,要是在set unused
column之前新增加的那列是定长型,并且有默认值,还有NOT NULL约束,情况又是怎么样呢?

经过实验,也不会再分配存储空间了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐