oracle如何优化海量更新

Posted

技术标签:

【中文标题】oracle如何优化海量更新【英文标题】:How to optimise massive updates in oracle 【发布时间】:2019-03-02 17:19:12 【问题描述】:

我需要在 oracle 中更新一个包含 ~40*10^6 记录的巨大表。 将被修改的行数大约为 10^7。 确定将要更新的行的查询很复杂并且涉及连接。仅识别将要更新的行的 id 就需要 30 分钟。

Select p.some_id from
(select some_id, col2,col3 from t1 where col2='someVulue' and col3 ='someValue') p 
inner join (select some_id from t2 where t2.col3='someValue') q
on p.some_id=q.some_id

现在为了进行更新,我需要添加另一个 join 或使用 IN 语句,这会使事情变得更糟。

有没有办法并行化这个? 还是进行批量更新(每次更新 25*10^4 行)?有没有办法告诉 oracle 只更新前 n 行?然后是 n->2n,然后是 2n->3n ... ?

该脚本将在 生产 环境中运行,因此无法进行表重建。

更新包括将布尔列设置为 true。(如果这有帮助)

【问题讨论】:

这是否会在服务窗口期间完成,以便您需要不惜一切代价快速运行?或者当有活跃用户时查询会运行吗?在一个事务中更新所有行的并行方法将非常昂贵,因此在使用数据库时不推荐。在这种情况下,我宁愿在一次选择中找到 ID 并将它们复制到临时表中。然后我会分批处理它们,每批之间都有一个提交。这意味着获得 ID 的选择成本很高,然后进行一些相当便宜的更新。 有关更新的更多详细信息可能会有所帮助。您只发布了select 查询。我想我理解 in 子查询和 Jon Heller 的 merge 建议可能会有所帮助,或者 update (select...join...) set...,然后是 dbms_parallel_execute 或普通 /*+ parallel */ 用于并行方面。 【参考方案1】:

执行大规模更新的最快方法是使用并行 DML,如下所示:

alter session enable parallel dml;
update /*+ parallel(16) */ some_table set some_column = 1;
commit;

有很多小问题需要注意。您需要有企业版。 UPDATE 将在表上获得排他锁,因此其他人将无法同时写入表。您的系统必须有足够的资源来支持大型 UPDATE,例如足够的重做、撤消、CPU、I/O 和配置合理的系统。

(您可能希望将我示例中的数字 16 更改为适合您的系统的数字。如果您想最大化性能,但可能以牺牲其他进程为代价,请将数字设置为等于该数字核心。)

Oracle 并行性很棒,但并没有真正优化。它使系统更努力地工作,而不是更智能。在尝试并行之前,您可能需要查看UPDATE 中使用的 SQL 语句。您可能还想尝试改用MERGEMERGE 语法一开始有点棘手,但它可以帮助避免重复连接,并允许哈希连接运行更快,以更改大部分行。

【讨论】:

【参考方案2】:

有几种方法。 1)将您的查询分成小块。 例如:按主键拆分表或添加子句 2)如果你需要经常运行这个,你可以考虑分区表,然后运行更新并行 3)检查您的索引是否正确构建 顺便说一句,如果 30 分钟不会导致您的应用程序出现性能问题或阻止其他查询,我认为这不是很长的时间,这是很正常的。

【讨论】:

【参考方案3】:

进行批量更新(每次更新 25*10^4 行)?有没有办法告诉 oracle 只更新前 n 行?然后是 n->2n,然后是 2n->3n,这里 n 为 10

 for loop i in 1..10
 loop
 update table1
 set column_val=x
 where rowid in (select rowid from table1
 where rownum >= (((i-1) * (25*10^4))+1) and rownum <= i*(25*10^4)
 );
 end loop;

【讨论】:

以上是关于oracle如何优化海量更新的主要内容,如果未能解决你的问题,请参考以下文章

如何把海量数据从 Oracle 导入到 Mongodb

使用用户定义的函数在 BigQuery 数据集中插入海量数据时如何优化性能

数据篇31 # 如何对海量数据进行优化性能?

数据篇31 # 如何对海量数据进行优化性能?

Oracle的极大数据量的分页查询问题

MySQL处理海量数据使得一些优化查询速度的方法