我需要更新 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 ... ?
该脚本将在生产 环境中运行,因此无法替代表重建。
更新包括将 bool 列设置为 true。(如果这有帮助的话)
最佳答案
执行大规模更新的最快方法是使用并行 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 语句。您可能还想尝试使用 MERGE
代替。 MERGE
语法一开始有点棘手,但它可以帮助避免重复连接,并允许散列连接运行得更快,以更改大部分行。
关于sql - 如何优化oracle中的海量更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54961037/