【发布时间】:2013-04-02 20:15:28
【问题描述】:
我已经搜索了一段时间,但找不到这个。我正在使用 Oracle 并且有一个类似于以下的 For 循环:
BEGIN
FOR YEARIDs IN (SELECT DISTINCT YEARID From MyTable)
LOOP
UPDATE (
SELECT ......
)
SET MyFlag = 1;
COMMIT; -- Added
END LOOP;
END;
AutoCommit 已打开,但在整个 FOR 循环完成之前似乎不会发生提交。因此,我在上面的代码中添加了 Commit 语句。这会导致任何意外结果,还是违反任何最佳实践? (即,当 AutoCommit 打开时,我不应该明确调用提交吗?)
谢谢, 斯科特
编辑:糟糕...我正在使用 Oracle 11g 和 Oracle SQL Developer 作为客户端。
编辑:到目前为止,感谢您的回复。在查询运行的时间点,正在生成和调整数据。不应有其他连接尝试访问数据。至于为什么我经常提交,在开发过程中,我对数据的子集运行查询并且查询运行得很好。该表包含大约 1400 万条记录,我正在测试大约 100k 条记录。该查询相当复杂,针对该子集运行大约 5 分钟。当我开始对整个表运行它时,查询运行了 14 多个小时并且无法更新任何记录。我的理论是持有这么多撤消信息可能会消耗开发服务器上的所有可用资源。如果我经常提交,那么撤消信息可以被释放和重用。是的,它很慢。但是如果查询真的会完成,即使需要一整夜,也可以将其移至测试服务器。 (并且性能调整可以在以后进行。)这个截止日期早就过去了。 (错过最后期限后,我被请来帮忙。我的专业领域不在 Oracle。)
【问题讨论】:
-
不应该提交在循环之外吗? (在 END LOOP 之后)。
-
自动提交将在语句完成后进行,在这种情况下,这是整个匿名块;不在
for循环之后。在这种情况下是学术性的,因为无论如何在循环之后都会注意到,但仍然......你为什么要如此频繁地提交? -
阅读这篇文章,了解 Oracle 自动提交(或缺少自动提交)的细微差别。 asktom.oracle.com/pls/apex/…。正如其他人所指出的,在每次迭代后提交是一个坏主意,但如果您有一个覆盖这些问题的用例,请在您的问题中分享。
-
到目前为止,我编辑了原始帖子以解决 cmets。
-
另外,在您更新后,possibly related question on DBA,其中包括到 AskTom 的链接,例如 this one。如果它用完了撤消,它会告诉你,所以其他事情正在发生;也许更新不是问题,而是您正在更新的视图很慢,也许您有触发器,也许是存档器问题,谁知道呢?看起来你需要做更多的分析,从解释计划开始,看看到底发生了什么。