`
winzenghua
  • 浏览: 1325144 次
  • 性别: Icon_minigender_2
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

ASKTOM 关于更新上百万的数据方法

阅读更多

假设如果我要更新数百万以上的数据, 我大概会选择不去’更新’ (UPDATE)吧.

我很有可能会用以下的方法:

CREATE TABLE new_table as select <在此更新> from old_table;
index new_table (给新的表创建索引)
grant on new table (授权于新的表)
add constraints on new_table (给新的表加上约束)
etc on new_table (加上其它所须的东西在新表)
drop table old_table (删除旧的表)
rename new_table to old_table; (给新的表重新命名为旧的表名)

在大多数的操作上, 你可以使用并行查询(PARALLEL QUERY)并加上NOLOGGING的语句来产生非常少重做日志(REDO LOG) 及 UNDO LOG . 这样的做法可以在很短的时间就可以更新数据了.

这绝对是可施行的方法, 而且也是我们一直在不断重复使用的方法. 我们其中的一个应用程式便用于这方法来更新含有数亿数据的表.

经我们的计算CURSOR … FOR LOOP 的方式将会需要53.7年来完成数据的更新. 我们采用INSERT INTO DUMMY TABLE的方式并加上NOLOGGING的语句的结果使我们在在30分以内就完成了数据更新.

在用NOLOGGING的语句, 假若系统中断, 只要再重新执行更新(UPDATE)就可以了.因为所有的数据还在原来的表. 当结束时(INSERT), 只要把表DUMMY(含有以更新的数据)跟原来的表中的分区(PARTITION)交换就可以了(译着注: 用exchange partition的语句).

更新表中FIELD2
(1) 首先, 创建表DUMMY,
create table xyz_HOLD as select * from xyz where rownum<1
Alter tablexyz nologging

(2) ) insert /*+ append parallel (xyzhold,12) */
into xyz_hold xyzhold (field1, field2, field3)
select /*+ parallel (x,12) */ xyz.field1, my_new_value_for_field2, xyz.field3
from xyz x
where <等等..>

(3) 当结束时, 可以给表重新命名 (RENAME)或是如果原来的表如是分区(PARTITION)的话, 与分区交换数据; 或更新所需要的分区就好了. 当然你必须重创索引(REBUILD INDECIES), 及其它所需的.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics