I want to find the best solution for an insert/update oracle function. My task is to collect some date from multiple tables (source tables) and bring them to a single table (destination table). Source tables getting inserts and updates in real time. My function must run ones/day to getting all new data and updated data to destination table. I identify my new / updated data by using a column (date) from source table based on a trigger witch update the date column with systimestamp at every insert/update.
My current code looks like this
for rec in (
select firstname, lastname, email, id
from people_source
where people_source.date > last_run_date
)
loop
merge into people_destionation dest
using ( select firstname, lastname, email, id from dual ) src
on (src.id=dest.id)
when matched then updated set
firstname=src.firstname,
lastname=src.lastname,
email=src.email
when not matched then
insert
(
firstname,
lastname,
email,
id
)
values
(
rec.firstname,
rec.lastname,
rec.email,
rec.id
);
exception when others ....
This solution make what I want, but I tested for 100k rows. I have source tables with 100 mil. rows and I try to find the best performance solution.
I also read about "Switching between PL/SQL and SQL engines" and I think this applies to me. Will it be a better idea to try to make functions with BULK COLLECT and FORALL?
I have not a very long experience in pl/sql, so I need more opinions and I thing here is a good place. Thanks. Best wishes.
Best Answer
In your code, you are issueing one SQL statement for every row you get from your
people_source
table. This is called row-by-row (read slow-by-slow) processing. For every query you make you force a context switch from PL/SQL to SQL engine and back which will add up pretty quickly.As a first step, you should try to implement the functionality using just SQL (in this way, you eliminate expensive SQL/PLSQL context switch altogether). Try to use the
merge
DML as it was meant to be used:In case this is slow, then we need more information (for example how many rows you expect to be merged, how are source/target tables created, are there any triggers, indexes) to be able to propose a way to make it faster (adding index on Id column, parallel execution, partitioning the table, eliminating triggers, disabling/recreating indexes, ...).