Sql 游标中更新的奇怪运行时行为

Sql 游标中更新的奇怪运行时行为,sql,oracle,cursor,oracle11g,Sql,Oracle,Cursor,Oracle11g,我有一张旧桌子和一张新桌子。在旧表中,有一个VARCHAR2列,名为number,其值类似于11-38D402342和11-38D402342/43。还有一些糟糕的数据,但从不为空 在新表中,有两个VARCHAR2列number\u left和number\u right。这两个字段是从旧表的数字列中填写的: number_left = nvl(substr(number,1,instr(number,'/',1)-1),number) number_right = substr(number

我有一张旧桌子和一张新桌子。在旧表中,有一个
VARCHAR2
列,名为
number
,其值类似于
11-38D402342
11-38D402342/43
。还有一些糟糕的数据,但从不为空

在新表中,有两个
VARCHAR2
number\u left
number\u right
。这两个字段是从旧表的数字列中填写的:

number_left  = nvl(substr(number,1,instr(number,'/',1)-1),number)
number_right = substr(number,1,instr(rtrim(number,'/'),'/',1)-length(substr(number,instr(number,'/'))))||substr(number,decode(instr(number,'/'),0,null,instr(number,'/')+1))
在做了一些其他决定之后,我们现在只需要再做一列。为了确保正确设置复制的数字,我决定使用旧表的数字和使用的转换来标识匹配的行

我有一个映射,但无法使用它,因为应用程序可以将左数字和右数字复制到新行中,并且必须也获取旧数字。因此,许多旧表可能被复制到新表中的多行中

我尝试使用以下代码:

declare
    left_num varchar2(255 char) := '';
    right_num varchar2(255 char) := '';
    pos number := 0;
    CURSOR c_number is
        select number from old_table;
begin
    for cur in c_number loop
        left_num := nvl(substr(cur.number,1,instr(cur.number,'/',1)-1),cur.number);
        if instr(cur.number,'/') = 0 then
          pos := null;
        else
          pos := instr(cur.number,'/')+1;
        end if;
        right_num := substr(cur.number,1,instr(rtrim(cur.number,'/'),'/',1)-length(substr(cur.number,instr(cur.number,'/'))))||substr(cur.number, pos);

        update new_table n
            set n.number = cur.snummer
            where n.number_left = left_num
            and (
              n.number_right = right_num
              or (
                n.number_right is null
                and right_num is null
              )
            );
    end loop;
end;
旧表中有170.000行,新表中有180.000行,因为还有一些新数据。花生

但奇怪的是: 一切似乎都很好,但在前14000行之后,速度变得非常慢,可能每秒3行。我认为它变得越来越慢


有什么想法吗?

与其让一群随机的初学者猜一猜,不如学习如何跟踪数据库中SQL的性能。有几种不同的方法可以让您深入了解语句的性能,但您将获得某种级别的DBA类型访问

这是一个包含在中的领域,但我建议您从Tim Hall的精彩概述开始