Oracle 11g enhancement add column

今天在ods 上给一张2亿+ 表增加一列,若该列非空,在11g 以前做法是增加一空列,然后等空闲的时候update .在11g 中不需要这样了.

11g 对于增加字段有一个性能增强的特性,在11g 之前的版本添加一个非空字段(默认值) ,会对表做个巨大的update,锁表, 产生大量的undo 和redo , 增加字段 11g 这个特性将默认值存储在元数据字典中,瞬间完成添加列的操作

在metalink 上发现的已有两个bug
Add Date Column To Table With Default Sysdate And Not Null Inserts Zeros [ID 602327.1]
Bug 8501439 - OERI[kghfrh:ds] / [kghfrempty:ds] / [17147] ORA-7445 [memcpy] with ANALYZE in a table with added column [ID 8501439.8]


根据一些资料,实验验证下 存储add column  的两个数据字典 sys.col$ 和 sys.ecol$


SQL> conn /as sysdba
Connected.
SQL> create table scott.t_addcolumn nologging as  select rownum id,text from dba_source;

Table created.

Elapsed: 00:00:17.82
SQL> oradebug setmypid
Statement processed.
SQL> oradebug event 10046 trace name context forever,level 8;
Statement processed.
SQL> alter table scott.t_addcolumn add (name varchar2(10) default 'N' not null);

Table altered.

Elapsed: 00:00:01.53
SQL> select * from scott.t_addcolumn where rownum<3;


        ID TEXT                                                                                    NAME
---------- -------------------------------------------------------------------------------------- ----------
         1 package STANDARD AUTHID CURRENT_USER is    -- careful on this line; SED edit occurs!       N
         2                                                                                            N



Elapsed: 00:00:01.01
SQL> oradebug event 10046 trace name context off;
Statement processed.
SQL> oradebug tracefile_name
/opt/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_19120.trc
SQL> !

vi /opt/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_19120.trc

update con$ set con#=:3,spare1=:4 where owner#=:1 and name=:2
END OF STMT
PARSE #3:c=30996,e=90188,p=8,cr=193,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1331203324127578
EXEC #3:c=1999,e=2173,p=0,cr=2,cu=6,mis=1,r=1,dep=1,og=4,plh=2574219287,tim=1331203324129854
STAT #3 id=1 cnt=0 pid=0 pos=1 bj=0 p='UPDATE  CON$ (cr=2 pr=0 pw=0 time=0 us)'
STAT #3 id=2 cnt=1 pid=1 pos=1 bj=51 p='INDEX UNIQUE SCAN I_CON1 (cr=2 pr=0 pw=0 time=0 us cost=1 size=25 card=1)'
CLOSE #3:c=0,e=2,dep=1,type=3,tim=1331203324130002
=====================
PARSING IN CURSOR #1 len=56 dep=1 uid=0 ct=3 lid=0 tim=1331203324130700 hv=2140575417 ad='4bfbf150' sqlid='7ub921xztd5pt'
select con#,spare1 from con$ where owner#=:1 and name=:2

=====================
PARSING IN CURSOR #8 len=453 dep=1 uid=0 ct=2 lid=0 tim=1331203325530200 hv=224718466 ad='4fc83da4' sqlid='60uw2vh6q9vn2'
insert into col$(obj#,name,intcol#,segcol#,type#,length,precision#,scale,null$,offset,fixedstorage,segcollength,deflength,default$,col#,property,charsetid,charsetform,spare1,spare2,spare3)values(:1,:2,:3,:4,:5,:6,decode(:5,182/*DTYIYM*/,:7,183/*DTYIDS*/,:7,decode(:7,0,null,:7)),decode(:5,2,decode(:8,-127/*MAXSB1MINAL*/,null,:8),178,:8,179,:8,180,:8,181,:8,182,:8,183,:8,231,:8,null),:9,0,:10,:11,decode(:12,0,null,:12),:13,:14,:15,:16,:17,:18,:19,:20)

=====================
PARSING IN CURSOR #1 len=37 dep=1 uid=0 ct=2 lid=0 tim=1331203325532210 hv=4050124187 ad='3cbc2774' sqlid='cqrnq6vsqgzcv'
insert into ecol$ values (:1, :2, :3)
END OF STMT
PARSE #1:c=1000,e=403,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1331203325532209
EXEC #1:c=1000,e=722,p=0,cr=2,cu=3,mis=1,r=1,dep=1,og=4,plh=0,tim=1331203325532996
STAT #1 id=1 cnt=0 pid=0 pos=1 bj=0 p='LOAD TABLE CONVENTIONAL  (cr=2 pr=0 pw=0 time=0 us)'
CLOSE #1:c=0,e=2,dep=1,type=3,tim=1331203325533068


=====================
PARSING IN CURSOR #4 len=97 dep=1 uid=0 ct=3 lid=0 tim=1331203351112343 hv=2759248297 ad='3e632170' sqlid='aa35g82k7dkd9'
select binaryDefVal, length(binaryDefVal) from ecol$           where tabobj# = :1 and colnum = :2
END OF STMT
PARSE #4:c=1000,e=706,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=1331203351112342
EXEC #4:c=1000,e=877,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=3081038021,tim=1331203351113316
FETCH #4:c=0,e=56,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,plh=3081038021,tim=1331203351113406
STAT #4 id=1 cnt=1 pid=0 pos=1 bj=123 p='TABLE ACCESS BY INDEX ROWID ECOL$ (cr=2 pr=0 pw=0 time=0 us cost=1 size=2028 card=1)'
STAT #4 id=2 cnt=1 pid=1 pos=1 bj=126 p='INDEX RANGE SCAN ECOL_IX1 (cr=1 pr=0 pw=0 time=0 us cost=1 size=0 card=1)'
CLOSE #4:c=0,e=2,dep=1,type=3,tim=1331203351113491



格式化:
[oracle@mbhvm ~]$tkprof /opt/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_19120.trc /opt/oracle/diag/rdbms/orcl/orcl/trace/addcolumn.log

TKPROF: Release 11.2.0.1.0 - Development on Thu Mar 8 18:54:11 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.


[oracle@mbhvm ~]$vi /opt/oracle/diag/rdbms/orcl/orcl/trace/addcolumn.log 


********************************************************************************

SQL ID: 8nhg2pdrzs3ww
Plan Hash: 0
insert into con$(owner#,name,con#,spare1)
values
(:1,:2,:3,:4)


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.01          0          0          0           0
Execute      1      0.00       0.00          0          1          6           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.00       0.01          0          1          6           1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
      0  LOAD TABLE CONVENTIONAL  (cr=1 pr=0 pw=0 time=0 us)

********************************************************************************

********************************************************************************

SQL ID: bajr90ryjd2w8
Plan Hash: 2574219287
update con$ set con#=:3,spare1=:4
where
 owner#=:1 and name=:2


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.01          0          0          0           0
Execute      1      0.00       0.00          0          2          6           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.00       0.01          0          2          6           1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
      0  UPDATE  CON$ (cr=2 pr=0 pw=0 time=0 us)
      1   INDEX UNIQUE SCAN I_CON1 (cr=2 pr=0 pw=0 time=0 us cost=1 size=25 card=1)(object id 51)

********************************************************************************

********************************************************************************

SQL ID: cqrnq6vsqgzcv
Plan Hash: 0
insert into ecol$
values
 (:1, :2, :3)


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          2          3           1
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.00       0.00          0          2          3           1

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: SYS   (recursive depth: 1)

Rows     Row Source Operation
-------  ---------------------------------------------------
      0  LOAD TABLE CONVENTIONAL  (cr=2 pr=0 pw=0 time=0 us)

********************************************************************************



可以看出更新了 sys.col$ 和 sys.ecol$ 数据字典



SQL> select * from sys.ecol$
 
  TABOBJ#     COLNUM BINA
---------- ---------- ----
    147549          3 4E
    147550          3 4E

Elapsed: 00:00:00.00

SQL> desc sys.ecol$
 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 TABOBJ#                                                                    NUMBER
 COLNUM                                                                     NUMBER
 BINARYDEFVAL                                                               BLOB

BLOB 字段

SQL> select utl_raw.cast_to_varchar2(dbms_lob.substr(BINARYDEFVAL)) AS TEL from sys.ecol$;



TEL
------------------------------------------------------------------------------------------------------------------------
N
N

Elapsed: 00:00:00.01


SQL> select obj#,name,default$ from sys.col$ where obj#=147549;

      OBJ# NAME                           DEFAULT$
---------- ------------------------------ ----------
    147549 ID
    147549 TEXT
    147549 NAME                           'N'

Elapsed: 00:00:00.00


证明了这两个数据字典存储的正是赋予的默认值'N'


另外,第一赋予的默认值,将永久的保存在ecol$中,如果我们修改这个默认值,那么,那么仅修改col$中的值,我们查询时也是从这个数据字典里取数据




资料引用:
http://tonguc.wordpress.com/2008/09/28/11g-enhancement-for-alter-table-add-column-functionality/
http://www.pythian.com/news/1660/adding-columns-with-default-values-and-not-null-in-oracle-11g/
http://blog.csdn.net/tianlesoftware/article/details/7226893

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23141985/viewspace-718325/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23141985/viewspace-718325/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值