【问题标题】:Optimising addition of new column in Oracle在 Oracle 中优化添加新列
【发布时间】:2013-10-31 05:05:06
【问题描述】:

我正在使用以下查询将列“DEPARTMENT”添加到表“EMPLOYEE”中。

ALTER TABLE EMPLOYEE ADD DEPARTMENT varchar(15);

然后使用以下查询将 DEPARTMENT 更新为“技术”

update EMPLOYEE set DEPARTMENT = 'Technology' where DEPARTMENT is null;

由于记录数量有限,这在开发环境中似乎运行良好,但在 Prod like Environment 中需要将近 1 小时,因为在 Prod 中有大约 2000 万条记录要更新,这是不可接受的。

我们正在考虑修改更新查询以删除 where 条件,如下所示。

update EMPLOYEE set DEPARTMENT = 'Technology';

这会有帮助吗?还是有其他方法可以优化此查询?

注意:使用oracle 11g数据库

【问题讨论】:

  • 删除WHERE子句?!你知道那是做什么的吗?首先在DEPARTMENT 上添加索引。
  • 删除 where 子句将使用我想要的“技术”更新所有现有记录?会变得更糟吗?
  • 尝试在您正在使用的表上使用索引..
  • 抱歉,我不太明白您在更改表后执行UPDATE。在这种情况下,语句很好,我相信添加索引不会有太大作用,因为它必须更新所有记录。

标签: sql oracle11g query-optimization


【解决方案1】:

你的两个陈述的组合:

ALTER TABLE EMPLOYEE ADD DEPARTMENT varchar(15);

                  +

update EMPLOYEE 
    set DEPARTMENT = 'Technology' 
  where DEPARTMENT is null;

等于

 ALTER TABLE EMPLOYEE ADD DEPARTMENT varchar(15) default 'Technology' not null;

当您使用 Oracle 11g 时,您将几乎在眨眼之间添加一个新列并为该列分配一个默认值,因为当新列定义为 not null 时,Oracle 会在数据字典,不再需要更新每一行。此外,在您开始插入新行或更新department 列的值之前,新添加的具有默认值的列不会占用空间。

简单演示:

SQL> create table big_table(
  2    col_1 number,
  3    col_2 varchar2(100)
  4  )
  5  ;
Table created

/* x2 for the sake of demonstration we just insert 600000 rows*/
SQL> insert into big_table(col_1, col_2)
  2    select level
  3         , dbms_random.string('l', 11)
  4      from dual
  5     connect by level <= 300000
  6  ;
300000 rows inserted

SQL> commit;
Commit complete

SQL> exec dbms_stats.gather_table_stats(user, 'BIG_TABLE');

PL/SQL procedure successfully completed

SQL> select count(*) from big_table;

  COUNT(*)
----------
    600000

添加新列+使用默认值更新

SQL> alter table big_table add department varchar2(10);
Table altered


SQL> set timing on;

SQL> update big_table set department='Technology';

600000 rows updated

Executed in 28.719 seconds

使用默认值添加新的NOT NULL

SQL> alter table big_table 
  2    add department2 varchar2(15) default 'Technology' not null;

Table altered


Executed in 0.015 seconds

【讨论】:

  • 同样适用于 10g 吗?由于 Prod 为 10g。
  • 11g 用于开发,10g 用于生产?
  • @DavidAldridge 我知道那不理想:-(
  • @Chillax 这是 11g 版本的新功能。不幸的是,这个(维护数据字典中的列默认值)特性在 10g 版本的 RDBMS 中不存在。在 10g 中,为列分配默认值需要更新每一行。
猜你喜欢
  • 2016-01-24
  • 2010-12-30
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2015-02-20
  • 1970-01-01
  • 2021-10-11
  • 2016-05-20
相关资源
最近更新 更多