我需要使用Oracle中的批量收集功能插入表中不存在的所有那些记录。我的代码在这里,这花费了太多时间。
forall i in 1 .. arr_upd_mbr.count save exceptions
insert into claim.member_contact(member_id_rx, addr_street, addr_apt,
addr_city, addr_state, addr_zip, contact_phone,
start_dt, end_dt, gender, dob)
select
arr_upd_mbr(i).member_id_rx, arr_upd_mbr(i).mbr_addr_street, arr_upd_mbr(i).mbr_addr_apt,
arr_upd_mbr(i).mbr_addr_city, arr_upd_mbr(i).mbr_addr_state, arr_upd_mbr(i).mbr_addr_zip || arr_upd_mbr(i).zip_reserve,
arr_upd_mbr(i).primary_phone, trunc(sysdate), arr_upd_mbr(i).elg_end_dt,
arr_upd_mbr(i).mbr_gender, arr_upd_mbr(i).mbr_dob
from dual
where not exists(select 1
from claim.member_contact
where member_id_rx = arr_upd_mbr(i).member_id_rx
and nvl(addr_street, '~') = nvl(arr_upd_mbr(i).mbr_addr_street, '~')
and nvl(addr_apt, '~') = nvl(arr_upd_mbr(i).mbr_addr_apt, '~')
and nvl(addr_city, '~') = nvl(arr_upd_mbr(i).mbr_addr_city, '~')
and nvl(addr_state, '~') = nvl(arr_upd_mbr(i).mbr_addr_state, '~')
and nvl(addr_zip, '~') = nvl((arr_upd_mbr(i).mbr_addr_zip || arr_upd_mbr(i).zip_reserve), '~')
and nvl(contact_phone, '~') = nvl(arr_upd_mbr(i).primary_phone, '~')
and nvl(gender, '~') = nvl(arr_upd_mbr(i).mbr_gender, '~')
and nvl(dob, v_last_date) = nvl(arr_upd_mbr(i).mbr_dob, v_last_date)
and sysdate between start_dt and end_dt);
exception
when e_dml_errors then
save_mem_change_exp(p_mbr_enrl_log_id_rx, 'MEMBER_CONTACT(Update)', arr_upd_mbr);
end;
答案 0 :(得分:4)
在FORALL中执行not exists
将严重降低批量操作带来的任何性能优势。
您尚未提供任何上下文,因此我们很难提供任何有意义的建议,但是通过重写代码可能会获得更好的性能。例如:
claim.member_contact
的全表扫描。也许您可以找到一种更好的识别现有地址的方法。