Sql 嵌套游标性能调整
我有两个游标,一个用于从包含50列和10000+数据的表中获取记录,另一个用于检查另一个大表(200万数据)中是否存在特定列。我应该将游标1中的所有记录写入一个文件,保存一年,如果游标2中存在该列,那么我应该将错误消息打印为存在,而不是删除它们。如果它不存在,那么我应该删除该行,并将其写入与已删除记录相同的文件和消息中。 我使用了一个嵌套游标,性能太差了,因为它每次都处理游标1和游标2之间的每一行Sql 嵌套游标性能调整,sql,oracle,performance,plsql,cursor,Sql,Oracle,Performance,Plsql,Cursor,我有两个游标,一个用于从包含50列和10000+数据的表中获取记录,另一个用于检查另一个大表(200万数据)中是否存在特定列。我应该将游标1中的所有记录写入一个文件,保存一年,如果游标2中存在该列,那么我应该将错误消息打印为存在,而不是删除它们。如果它不存在,那么我应该删除该行,并将其写入与已删除记录相同的文件和消息中。 我使用了一个嵌套游标,性能太差了,因为它每次都处理游标1和游标2之间的每一行 CURSOR cursor1 IS
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;
这个怎么样?三步操作: 步骤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:如果必须,将保存在LOG_表中的行存储到您的文件中。如果没有,请将它们保留在
LOG\u表中utl\u文件中。将行放入循环将产生开销。请尝试将行追加到lv\u msg,直到字符串长度为32767字节,然后只写入一次。
这肯定会减少I/O,性能应该得到提高。没有足够的声誉来写评论,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
就像把它存储在临时表中一样。恐怕我不能这么做。我应该附加UTLYFIL.PUTYLIN而不是写它吗?你不想在中间记录一个LVIMSG。继续用新行(chr(10))附加到lv_msg,当长度刚好小于32767时,写入文件并将lv_msg重置为null。我尝试了这个方法,性能只提高了几分钟。感谢you@Doranaut我尝试了单查询,性能比以前好多了。感谢you@Doranaut-当我尝试向表1A添加更多条件时,它会一直运行。我只是在加入之前使用和添加conditions@arsha附加条件可能会改变执行计划。查询文本及其执行计划至少需要说明任何内容。