Oracle正在尝试更新列
我有一个包含十亿条记录的表,只需要无条件地更新一个字段 update set flag='N'这是我的更新查询,需要很长时间。Oracle正在尝试更新列,oracle,Oracle,我有一个包含十亿条记录的表,只需要无条件地更新一个字段 update set flag='N'这是我的更新查询,需要很长时间。 如何快速执行此操作。请勿更新。使用CTA,然后重命名新表 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; 要
如何快速执行此操作。请勿更新。使用CTA,然后重命名新表
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;
要小心,因为你要扔掉旧桌子。第一个想法是:
如果您有空间:
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;
与简单的更新相比将非常快
如果一切正常,就放下你的旧标签
第二个想法a:
更新/*+parallelyour_tab 8*/your_tab set flag='N'
将是
比noparallel版本更快。如果您真的不能等待那么长时间来运行更新,并且可以在标志为null而不是“N”的情况下生存,那么您可以在未经测试的情况下很快完成此操作,但应该可以工作:
alter table my_tab set unused column flag;
alter table my_tab add (flag char(1));
如果希望回收一些空间,您可以稍后删除未使用的检查点。请注意,删除需要一些时间,因此如果选择这样做,请小心
希望有帮助
编辑:由于@TTT,显然在11g中Oracle可以在数据字典中存储一个默认值,而不是像我以前的经验那样对所有行执行更新。这意味着您可以使用“N”值而不是NULL。只需确保指定NOTNULL以及默认值:
没有NOT NULL和NOT default,它花费了20秒,显示这个fast=true技巧只有在指定NOT NULL和一个真正有意义的默认值时才有效。首先使用索引,然后执行更新!Asha没有条件,所以索引表也没有帮助。除此之外,无论如何,创建索引可能要比更新花费更长的时间。@Asha:你可能不得不接受它……当需要修改记录时,索引是一个性能拖累因素。我认为你可以添加一个带有默认值的NOTNULL列,而无需等待几分钟或几小时。应该只需要1秒钟左右。阅读这里:@TTT谢谢你的链接。我认为默认的“N”将需要10亿行的时间,但我可能错了,也许11g处理方式不同。@TTT再次感谢,这篇文章非常有趣。如果11g真的不需要用默认值进行更新,我会做一个快速测试并用默认值更新我的答案!
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