2

我有一个包含数十亿条记录的表,只需要更新一个没有条件的字段。

update <table name> set flag='N'这是我的更新查询,需要很长时间。如何使其快速执行。

4

3 回答 3

2

If you really cannot wait that long to run your update, and can live with the flag being null instead of 'N', then you can do this very quickly (untested, but should work):

alter table my_tab set unused column flag;

alter table my_tab add (flag char(1));

You can later drop unused with checkpoints if you care to reclaim some space (note that the drop will take some time, so be careful if you choose to do this).

Hope that helps

EDIT: Thanks to @TTT for this article, apparently in 11g Oracle can store a default value in the data dictionary rather than performing an update to all rows (what I expected from previous experiences). This means you can use 'N' value instead of NULL. Just make sure you specify NOT NULL as well as the default value:

SQL> set timing on
SQL> drop table test1
Table dropped.
Elapsed: 00:00:00.23

SQL> create table test1
(
col1 varchar2(10),
flag char(1)
)
Table created.
Elapsed: 00:00:00.14

SQL> insert into test1
select 'x','Y'
from dual
connect by level <= 1000000
1000000 rows created.
Elapsed: 00:00:02.09

SQL> alter table test1 set unused column flag
Table altered.
Elapsed: 00:00:00.07

SQL> alter table test1 add (flag char(1) default 'N' not null )
Table altered.
Elapsed: 00:00:01.01

Without the "NOT NULL" and just a default, it took over 20 secs, showing this "fast=true" trick only works when specifying not null and a default (which makes sense really).

于 2012-06-22T10:52:13.280 回答
0

不要更新。使用 CTAS,然后重命名新表。

CREATE TABLE T_NEW NOLOGGING PARALLEL AS
SELECT COL1, COL2, 'N' FLAG FROM T_OLD;

然后应用旧表中的索引、约束或授权。如果你忘记了这一步,你会受苦。

DROP TABLE_T_OLD;
RENAME T_NEW TO T_OLD;

尽量小心,因为你要丢弃旧桌子。

于 2012-06-22T10:42:29.930 回答
0

第一个想法: 如果你有空间:

  create table tmp_tab as select col1, ..., coln, "N" as flag 
  from your_tab; 

  rename table your_tab to your_tab_old; 

  rename tmp_tab to your_tab;

与简单更新相比会非常快。

如果一切正常,请删除 your_tab_old。

第二个想法:

update /*+parallel(your_tab 8)*/ your_tab set flag='N';

将比非并行版本更快。

于 2012-06-22T10:44:15.880 回答