【问题标题】:Oracle stored procedure performance issueOracle 存储过程性能问题
【发布时间】:2016-09-18 09:18:40
【问题描述】:

共有三个表,TA、TB 和 TC。 TA 中的一行映射到两个表中的 TB 槽列中的大约 10 行。 TB 有一个 CLOB 列。 TC 具有与 TB 相同的列名和类型,但没有主键、外键或任何索引。 TA 大约有 100 万行,TB 有 2000 万行,TC 是空的。并非 TB 中的所有行在 TA 中都有对应的行,只有一半(1000 万)在 TA 中有对应的行。

我需要做的是将 TB 中与 TA 中具有关联行的行复制到 TC。

在存储过程中,我使用游标循环遍历 TA,对于 TA 中的每一行,选择 TB 中的关联行,并用一条语句插入到 TC 中,如

insert into TC select * from TB where TB.col = :value

Commit在TA中每五行处理完后发出。

问题是这个简单的存储过程一开始运行得很快,但变得越来越慢。对于 TA 中的前 1000 行,它需要 1.9 秒, 第二个1000行需要14秒,第三个1000行需要37秒,越来越不能接受了。

【问题讨论】:

  • 您可能需要更正该句子:TC 与 TC 具有相同的列名和类型。为什么你需要一个存储过程来完成这个任务?对于性能问题,从初始查询中导出数据然后批量加载可能会更好。
  • 考虑减少提交次数。在 TA 中每五行提交一次,您将获得 200 万次提交,从而导致大量日志文件同步。尝试提交每 100 行 TA。
  • 我尝试用一​​条 SQL 语句来做,但是 5 小时后 SQL 的执行没有完成。
  • 但是在 TB 中匹配 TA 中的行,然后使用批量操作将行放到 TC 中,例如每个批量 1000 行,单次选择可能会更有效。
  • @KamilG。抱歉,卡米尔 - 我看到你已经提出了类似的建议:)

标签: oracle performance stored-procedures


【解决方案1】:

如果您想在 pl/sql 中执行此操作,请尝试以下操作:

declare
    cursor src is
        select tb.*
        from    tb
        where exists (
            select null
            from   ta
            where <ta's primary key matches tb's primary keys>
            );
  type t_bulk is table of src%rowtype;
  v_bulk t_bulk;
begin
  open src;
  loop
    fetch src bulk collect into v_bulk limit 1000;
    forall i in 1..v_bulk.count
      insert into tc
        values v_bulk(i);
    commit;
    exit when v_bulk.count < 1000;
  end loop;
  close src;
end;

我现在无法访问 Oracle db - 这只是来自内存,可能有一些语法错误。

更新:TA 和 TB 之间的简单连接可能比使用 exists 更好。只要src 准确生成您想要插入到 TC 中的行。

【讨论】:

  • 我试过了,问题一样,一开始跑的很快,很快就慢到不能接受了。
  • 嗯 - 听起来像是某种资源争用,而不是你的代码问题。你有什么样的安装 - 大/小?
猜你喜欢
  • 2013-07-15
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多