sql嵌套游标性能调优

hiz5n14c  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(277)

我有两个游标,一个用于从包含50列和10000+个数据的表中获取记录,另一个用于检查另一个大表(200万个数据)中是否存在特定的列。我应该将游标1中一年的所有记录写入一个文件,如果游标2中存在该列,那么我应该将错误消息打印为exists,而不是删除它们。如果它不存在,那么我应该删除该行,并将其写入与已删除记录相同的文件和消息中。我使用了一个嵌套的游标,性能太差了,因为它每次都处理游标1和游标2之间的每一行。

CURSOR cursor1
         IS           
             select a.* ,a.rowid
              FROM table1 a 
              WHERE a.table1.year = p_year;

    CURSOR check_c2(lv_cd )
     IS
      Select DISTINCT 'Y' 
       from table2
       where table2 ='R'
       AND table2.year= p_year
       and table2_code= lv_cd ;

BEGIN :
   FOR r in cursor1 LOOP
            EXIT WHEN cursor1%NOTFOUND;

              OPEN check_c2(r.cd);
              FETCH check_c2 INTO lv_check;
                IF check_c2%NOTFOUND THEN
                    lv_check :='N';
                END IF;
                CLOSE check_c2;

                  IF lv_check ='Y' THEN
                   lv_msg =(r.col1,r.col2....r.col50, R code exists do not delete)
                   utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);

                ELSE 
                  DELETE from table1 where rowid= r.rowid
                  lv_msg =(r.col1,r.col2....r.col50, delete row)
                   utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);
                   END IF;
                   END LOOP;
xzlaal3s

xzlaal3s1#

没有足够的声誉写评论som将写作为一个答案。
你没有试着添加一些时间标记来理解哪些部分花费的时间最多吗?
表2是否有按年份和代码列出的索引?cursor2查询的解释计划是什么?如果是-年份+代码组合的平均行数是多少?如果从表2中总体上选择的数据量很大,那么使用表2上的完整扫描/索引范围按年份扫描、分组和哈希左外联接(从表1到表2)来执行单个查询可能会更快

select a.*, a.rowid, nvl2(c.code, 'Y', 'N') check_col
from table1 a,
(
    select distinct code
    from table2 b
    where b.year = p_year
) c
where a.year = p_year
  and c.code(+) = a.cd
elcex8rz

elcex8rz2#

这个怎么样?三步操作:
步骤1:“保存”稍后将删除的行

create table log_table as
select *
from table1 a
where exists (select null
              from table2 b
              where b.year = a.year
                and b.code = a.code
             );

步骤2:删除行:

delete from table1 a
where exists (select null
              from table2 b
              where b.year = a.year
                and b.code = a.code
             );

第3步:如果必须的话,将保存在logu表中的行存储到您的文件中。如果没有,就把它们放进去 LOG_TABLE .

lymgl2op

lymgl2op3#

utl\ U file.put\在循环中的行将是一个开销。请尝试附加到lv\ U msg,直到字符串的长度为32767字节,然后只写一次。这肯定会减少i/o,性能应该得到提高。

相关问题