字段名称存储在表中时如何改进数据加载
Posted
技术标签:
【中文标题】字段名称存储在表中时如何改进数据加载【英文标题】:How to Improve data loading when field name is stored in a table 【发布时间】:2014-03-16 01:04:32 【问题描述】:我需要使以下代码高效(加速)。它非常慢。 我正在更新并插入到多个表中,要更新的字段名称存储在一个临时表中,布局如下:
变量名 变量名的值 foreign_key1 foreign_key2 数据库表名代码:
DECLARE
TYPE t_char_array IS TABLE OF VARCHAR2(32) INDEX BY BINARY_INTEGER;
t_cursor SYS_REFCURSOR;
t_id t_char_array;
t_varnm t_char_array;
t_valuex t_char_array;
t_fpk1 t_num_array;
t_dbtable t_char_array;
t_fpk2 t_num_array;
t_row_count NUMBER :=0;
sql_stmt VARCHAR2(700);
sql_cursor VARCHAR2(300);
sql_inserr VARCHAR2(100);
BEGIN
sql_cursor :='SELECT id, varnm, valuex,fpk1,dbtable, fpk2 FROM '||&tableq;
OPEN t_cursor for sql_cursor;
LOOP
FETCH t_cursor
BULK COLLECT INTO t_id, t_varnm, t_valuex, t_fpk1, t_dbtable,t_fpk2
LIMIT 1000;
EXIT WHEN t_row_count = t_cursor%ROWCOUNT;
t_row_count := t_cursor%ROWCOUNT;
FOR i IN 1..t_id.count loop
if t_dbtable(i) =' Temp_table' then
sql_stmt:='UPDATE Temp_table SET '||t_varnm(i)||' =:1
WHERE pk = '||t_fpk1(i)||' and dictionary_pk = '||t_fpk2(i) ;
if t_vartype(i) ='D' then
EXECUTE IMMEDIATE sql_stmt using to_date(t_valuex(i),'YYYYMMDD');
else
EXECUTE IMMEDIATE sql_stmt using (t_valuex(i));
end if;
if sql%rowcount = 0 then
sql_stmt:='insert into Temp_table (pk, fpk2,'||t_varnm(i)||' )
VALUES (seq_steps.nextval,t_fpk2(i),t_valuex(i))';
end if;
end if;
end loop;
exit when t_id.count < 1000;
end loop;
commit;
【问题讨论】:
【参考方案1】:将多个 INSERT 和 UPDATE 组合成较少数量的 MERGE。这种方法将从输入表中读取更多次,但可能会显着减少动态 SQL 的数量。这实际上是更多合乎逻辑的工作,但它可能会执行得更好,因为它减少了 SQL 和 PL/SQL 之间的切换。
begin
for merges in
(
select distinct id, varnm, vartype
from &tableq
where dbtable = ' Temp_table'
) loop
execute immediate '
merge into temp_table
using
(
select fpk1, fpk2,
'||case when mergest.vartype = 'D' then
'to_date(valuex, ''YYYYMMDD'')'
else 'valuex' end||'
from &tableq
where varnm = :merges_varnm
and vartype = :merges_vartype
) new_data
on
(
temp_table.pk = new_data.fpk1
and
temp_table.dictionary_pk = new_data.fpk2
)
when matched then update set
'||merges.varnm||' = new_data.valuex
when not matched then insert(pk, fpk2, '||merges.varnm||')
values(seq_steps.nextval, new_data.fpk2, valuex)
' using merges.varnm, merges.vartype;
end loop;
end;
/
【讨论】:
感谢您的导入。我尝试了这种方法,它的性能比上面的差一点。同样令人困惑的是,我仅使用 11k 条记录对此进行了测试,但加载数据需要 46 分钟以上。有没有办法在我的情况下使用 forall?以上是关于字段名称存储在表中时如何改进数据加载的主要内容,如果未能解决你的问题,请参考以下文章