sql - 如何优化oracle中的海量更新

标签 sql oracle sql-update sql-optimization

我需要更新 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/

相关文章:

sql - PostgreSQL - 从长格式到宽格式

sql - PL/SQL 是否具有与 Java 等效的 StringTokenizer?

mysql - 在一个查询中更新多个 MySQL 表时,是否始终保证分配顺序?

sql - 更新 MS SQL 列中的部分字符串

mysql - 单个查询中的 mysql 多个插入是原子的吗?

sql - MacOS 上的 Azure PowerShell - 运行脚本文件

mysql - 如何根据本地服务器时间获取每个州的基于时间的数据?

SQL Server : error could not find type in assembly during dll trigger creation

linux - Oracle:创建 keystore

java - 获取前几个月的第一个和最后一个日期