我必须更新有大约93万条记录的表,在开始DB每5秒更新10 k记录,现在大约60万条更新记录后,更新下一条10k记录需要30-60秒,不要知道为什么我要更新空的列。
我使用循环提交每10 k记录:
LOOP
UPDATE TABLE
SET DATE_COLUMN = v_hist_date
WHERE DATE_COLUMN IS NULL
AND ROWNUM <= c_commit_limit
AND NOT_REMOVED IS NULL;
EXIT WHEN SQL%ROWCOUNT = 0;
COMMIT;
END LOOP;
您是否有任何想法为什么它如此减速以及如何加快此更新?
答案 0 :(得分:5)
更新也是查询。您尚未发布解释计划,但鉴于您正在过滤列为空的列,您的语句似乎可能正在执行全表扫描。这当然适合你描述的行为。
这是怎么回事。 FTS找到10000行的第一个循环几乎立即符合WHERE标准。然后退出循环并重新开始。这次FTS再次读取相同的块,包括它在上一次迭代中更新的那些,然后才能找到它可以更新的下一个10000行。等等。每个循环都需要更长的时间,因为全表扫描必须为每个循环读取更多的表。
这是在循环内随机提交的惩罚之一。现在可能为时已晚,但更好的方法是跟踪索引列,例如主键。使用这样的跟踪密钥将允许索引扫描跳过您已访问过的行。