插入程序起初运行速度很快,但在 n 条记录后速度变慢

Insert procedure is working fast at first but slows down after n number of records

我们正在对 Oracle 19c 中的 table 进行批量收集插入。逻辑如下

    loop 
       fetch cursor c bulk collect 
        into v_row limit 1000  --v_row is table of source_table%rowtype
        exit when (v_row.count) = 0;
        for i in v_row.first .. v_row.last 
         loop
         --do processing here, assign v_row(i) values to v_target_table%rowtype variable
         --at the end we are extending a nested table and populating it with this v_target_table row
         v_tar_tab.extend;
         v_tar_tab(v_tar_tab.count) := v_target_table;
         end loop;
    end loop;
    --insert with forall
    forall i in v_tar_tab.first .. v_tar_tab.last 
     insert into target_table 
     values v_tar_tab (i);
    v_tar_tab := t_tar_table();  -- is table of target_table%rowtype
    commit;

问题是在这种特殊情况下源 table 有 300,000 行,对于前 100,000 行,插入工作非常快,但之后每 1000 次提取的时间都在增加,总时间为与前 100,000 行所花费的时间相比,其余 200,000 行太大了。 为了看到这一点,我们添加了一个计数器变量,并且在每次提取中将该计数器变量增加 1000,并在我们的日志 table 中记录该计数器的迭代次数和值。在第 95 次到第 100 次迭代之后,其中获取并处理了 100 000 行,过程变慢了。

循环内没有提交,目标 table 设置为无日志记录,并且在执行此插入过程之前禁用其约束和索引。我想不出为什么它对前 n 行运行速度快而对其余行运行速度慢的任何原因。关于应该更改的内容有什么想法吗?

如果需要注意,游标 c 中的 select 语句与提示并行运行。我在 insert into 语句中添加了 APPEND_VALUES 提示,但它并没有改变整体行为或时间。

查看与撤消记录相关的会话统计信息。查询开始时间和从中执行提取时间之间的差异可能会对性能产生影响,因为我们保证 return 记录在查询开始时保持原样。

如果源 table 正在执行事务 activity,那么我们需要撤消这些更改作为获取过程的一部分。

演示该费用的视频here