Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle正在尝试更新列_Oracle - Fatal编程技术网

Oracle正在尝试更新列

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; 要

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

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;
要小心,因为你要扔掉旧桌子。

第一个想法是: 如果您有空间:

  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