在oracle 11gR2版本中,对大表增加带默认值的字段,需要拆分成多个步骤,否则会长时间锁表。如下图:

对260万数据的表加带默认值的字段,执行超过2分钟。

我们的规范做法步骤为:

(1)加字段

alter table  T_ORDER add tstatus varchar2(20);

(2)批量更新数据

declare

n_count number;

begin

select ceil(count(1)/100000) into n_count

from T_ORDER where tstatus is null;

for i in 1..n_count loop

update T_ORDER set tstatus='1' where tstatus is null and rownum<=100000;

commit;

end loop;

end;

/

(3)增加默认值属性

alter table TABLE_NAME modify tstatus default '1' not null;

在19c中不再需要如此繁冗的操作了,添加带默认值的字段可以瞬间完成:

实验准备:  create table test(
owner varchar2(30),
object_name varchar2(128),
object_type varchar2(30),
created date
);
insert into test 
select owner,object_name,object_type ,to_Date('20190101','yyyymmdd')+60*dbms_random.value from all_objects;
commit;
--重复执行insert操作,插入200万数据
insert into test select * from test;
commit;

SQL> select count(1) from test;

COUNT(1)
----------
   3461376

oracle11gR2版本:
会话1 会话2
结论1:在oracle11gR2版本中,进行添加列、修改列的默认值操作时,如果其他会话中没有未提交的ddl、dml操作,则可以瞬间完成。 SQL> set timing on
SQL> alter table test add col2 varchar2(10) ;

Table altered.

Elapsed: 00:00:00.00
SQL> 
SQL> 
SQL> alter table test modify col2 default '1';

Table altered.

Elapsed: 00:00:00.00
SQL> 
SQL> select count(1) from test where col2='1';

COUNT(1)
----------
         0

Elapsed: 00:00:00.04

结论2:在oracle11gR2中,直接添加带默认值的列,执行时间和表的数据量相关 SQL> alter table test add col3 varchar2(10) default '1';

Table altered.

Elapsed: 00:01:49.02
SQL> SQL> SQL> 
SQL> alter table test add col4 date default sysdate;

Table altered.

Elapsed: 00:02:04.62

结论3:当有DML操作未提交时,添加带默认值的列将报错(获取独占锁失败)。添加列不带默认值时,会等待dml操作提交(释放行级锁)后才可执行完成。 SQL> set time on
15:17:50 SQL> delete from test where rownum=1;

1 row deleted.

SQL> set time on
15:18:11 SQL> alter table test add col5 varchar2(10) default '1';
alter table test add col5 varchar2(10) default '1'
            *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

Elapsed: 00:00:00.00
15:18:16 SQL>  alter table test add col5 varchar2(10);

15:17:54 SQL> commit;

Commit complete.
15:18:43 SQL>

Table altered.

Elapsed: 00:00:20.35
15:18:43 >

结论4:添加默认值带默认值、非空约束时,如果没有DML阻塞,可以瞬间完成;如果有DML操作未提交,则需等待直到DML操作提交才可完成 15:24:50 SQL> alter table test add col6 varchar2(10) default '1' not null;

Table altered.

Elapsed: 00:00:00.01

15:27:55 SQL>  delete from test where rownum=1;

1 row deleted.

15:28:01 SQL> alter table test add col7 varchar2(10) default '1' not null;
15:28:47 SQL> commit;

Commit complete.

15:29:04 SQL>

Table altered.

Elapsed: 00:00:09.27
15:29:04 SQL>

oracle19c版本 实验准备操作相同,数据量基本一致
SQL> SQL>  select count(1) from test;

COUNT(1)
----------
   3479400

会话1 会话2
结论5:在19c版本中,增加带默认值、无非空约束的列,可以瞬间完成。如果有DML操作未结束,仍需等待该操作完成才可以结束。 SQL> set timing on
SQL> alter table test add col3 varchar2(10) default '1';

Table altered.

Elapsed: 00:00:00.01
SQL> 
SQL> alter table test add col4 date default sysdate;

Table altered.

Elapsed: 00:00:00.02

SQL> set time on
15:43:01 SQL> delete from test where rownum=1;

1 row deleted.

15:43:07 SQL> alter table test add col5 varchar2(10) default '1';
15:43:03 SQL> commit;

Commit complete.

15:43:24 SQL>

Table altered.

Elapsed: 00:00:05.76
15:43:24 SQL> 15:43:24 SQL>

在19c官方文档中有如下描述:

直译为

11.2版本中 alter table add column with default value的操作正常不会阻塞,但在使用supplemental log时会降级为阻塞操作。

实际测试该操作,将数据库开启最小辅助日志、表开启辅助日志( alter table testu.test2 add supplemental log data(all) columns;),然后对test表使用OGG同步。操作都可以瞬间完成。这里还没太明白,后续有进展再补充。

总结:

在11gR2版本中增加带默认值的列时,需要指定not null属性,即可瞬间完成;否则锁表时间较长。

在19c版本中 增加带默认值的列时,不管是否包含not null属性,都可瞬间完成。

操作需要在业务低峰期操作,避免操作时有dml操作对其造成阻塞。

感悟:

数据库中的DML操作,主要需要避免大事务造成的锁表时间长、占用redo及undo等资源巨大、资源不足时回滚操作不可控等问题;

DDL操作时除了操作时间,还需要考虑表的独占锁对其他操作的阻塞问题。

随着数据库版本的迭代,功能愈加完善,很多经验已经不再适用了。适用新版本数据库前,应该对规范、操作手册进行测试,与时俱进,提高效率。

oracle增加字段带默认值相关推荐

  1. mysql增加字段设默认值_mysql原表增加字段且设置默认值及修改字段默认值

    -- 增加字段及注释 alter table sr_zjff_main add zjbzjxbj int(1) DEFAULT '0' COMMENT ''; alter table sr_main_ ...

  2. 添加列oracle默认值,Oracle 11g增加列,并带默认值的新特性

    在Oracle 11g以前,如果要在一个大表中增加一列,并设置默认值,那将是一个非常悲剧的事情.有些时候不得不选择在线重定义功能来实现 Oracle 11g增加列,并带默认值的新特性 [日期:2014 ...

  3. mysql修改表中某个字段的默认值

    Mysql中用SQL增加.删除字段,修改字段名.字段类型.注释,调整字段顺序总结 在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改表或 ...

  4. mysql给字段设置默认值,以及mysql的严格模式

    一.背景 在插入数据库时,报错#1364,后来才知道是字段在创建的时候,没有设置默认值的原因.关于默认值,我们都知道设置默认值为0或者null的时候,就算我们不插入该字段,数据库也会自动按照默认值填充 ...

  5. PowerDesigner中如何给字符串字段设置默认值 .

    参考:http://www.cnblogs.com/navy235/archive/2011/10/18/2216443.html 在PowerDesigner12.5中,给varchar或nvarc ...

  6. 关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别

    一.背景 根据业务需求,发现以前的同事在设计表的时候,很多字段都没有设置默认值.在mysql5.7版本之后,没有设定默认值的字段,在严格模式下是很容易报错的,所以我这边需要先给每个字段加上一个默认值. ...

  7. Python中的Optional和带默认值的参数

    文章目录 带默认值的参数 Typing.Optional类 Optional[X]等价于Union[X, None] 带默认值的参数 在Python中的类或者函数中,若参数在声明时附带了它的默认值,则 ...

  8. mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...

    一.背景 根据业务需求,发现以前的同事在设计表的时候,很多字段都没有设置默认值.在mysql5.7版本之后,没有设定默认值的字段,在严格模式下是很容易报错的,所以我这边需要先给每个字段加上一个默认值. ...

  9. mysql中IFNULL(字段名,默认值) 给null设置默认值

    SELECT IFNULL(字段名,默认值)  as 别名 FROM 表名;

最新文章

  1. RAID0,RAID1,RAID10,RAID5
  2. 导入技能要素三大类_教学技能之导入技能(值得收藏)
  3. java applet 游戏_Java Applet实现五子棋游戏
  4. 初中数学知识点总结_初中数学知识点总结大全_经典版_
  5. 关于vue-cli3中配置请求跨域的问题
  6. C语言实现一个随机测试加减乘除,编写程序:C语言实现一个随堂测试,能进行加减乘除运算...
  7. (47)fs创建多级目录
  8. Yahoo的14条准则
  9. 汇编语言上机考试三星题——加密的key和明文字符串(二)
  10. ios系统安装包下载_iOS在后台自动升级?一招教你屏蔽iOS更新
  11. 微信登录报错40125和-6签名秘钥问题解决方案
  12. sql注入学习笔记1
  13. 【云原生之K8s】 Pod基础概念
  14. 需求分析岗的一般工作流程
  15. Web IDE落地全记录(一)
  16. CAD高版本窗体阵列LISP_如何把CAD高版本阵列对话框在低版本调出来?
  17. 一个高尚的人,一个纯粹的人,一个有道德的人,一个脱离了低级趣味的人,一个有益于人民的人。...
  18. Unity3D for VR 学习(5): VR Gaze Input
  19. 2021年,谁发现了边缘计算的赚钱生意?
  20. CMS知识小结及wordpress的安装与漏洞复现

热门文章

  1. 计算机软件展望未来,计算机软件科学家谢涛:星辰大海,求思进取
  2. 快讯:好奇号传回信息,凿岩工作准备完毕
  3. PC端品优购网页制作(common.css)2
  4. 游戏陪玩平台系统启动页黑屏情况,该如何解决?
  5. cookie获取的两种方法
  6. Android 版本更新(非热更新) 适配7.0更新 以及三星 note系列读取内存相关目录无权限问题
  7. 杭州公积金修改预留手机号
  8. 什么是面向对象编程?
  9. 谷歌浏览器如何开启全黑模式
  10. 【华为 OJ】记负均正2