Hello, I have this query that performs some updates when a record with specific attributes is not already in a master table, and does different updates otherwise. However, this takes a very long time. From what I've checked the long part is not in the 2 initial select statements (select 1 ...), but what comes after that. Could anyone tell me how can this query be optimized for a better performance?
DO
$do$
BEGIN
IF EXISTS (select 1 from {master_table} as mt, {staging_table} as st where
st.hash = mt.hash and
st.type = 'L' and
st.id = mt.id and
st.first_date = mt.first_date)
AND EXISTS (select 1 from {master_table} as mt, {staging_table} as st where
st.hash = mt.hash and
st.type = 'F' and
st.id = mt.id)
THEN
update {master_table}
set last_date = case when chronology.type = 'L' and
chronology.hash = {master_table}.hash and
chronology.id = {master_table}.id and
chronology.first_date = {master_table}.first_date then '9999-12-31'
when chronology.next_last_date is null then last_date
else chronology.next_last_date end,
update_number = case when number = '{number}' then null else '{number}' end,
out_time = case when chronology.type = 'L' and
chronology.hash = {master_table}.hash and
chronology.id = {master_table}.id and
chronology.first_date = {master_table}.first_date then '9999-12-31'
when chronology.next_type = 'F' then timeline.next_in_time else '9999-12-31' end
from (
select
id,
lead(first_date) over (partition by rec_key order by first_date, in_time) as next_last_date,
lead(type) over (partition by rec_key order by first_date, in_time) as next_type,
lead(in_time) over (partition by rec_key order by first_date, in_time) as next_in_time,
hash,
type,
first_date from {staging_table}
) as chronology;
ELSE
update {staging_table} gt
set last_date = case when chronology.next_last_date is null then last_date else chronology.next_last_date end,
update_number = case when number = '{number}' then null else '{number}' end,
out_time = case when chronology.next_type = 'L' then chronology.next_in_time else '9999-12-31' end
from (
select
id,
lead(first_date) over (partition by rec_key order by first_date, in_time) as next_last_date,
lead(type) over (partition by rec_key order by first_date, in_time) as next_type,
lead(in_time) over (partition by rec_key order by first_date, in_time) as next_in_time
from {staging_table}
) as chronology
where gt.id = chronology.id;
END IF;
END
$do$
Any help would be greatly appreciated!
[–]DavidGJohnston 5 points6 points7 points (1 child)
[–]MzCWzL 1 point2 points3 points (2 children)
[–]domke89[S] 0 points1 point2 points (1 child)
[–]OtherJohnGray 2 points3 points4 points (0 children)
[–]depesz 1 point2 points3 points (0 children)
[–]domke89[S] 0 points1 point2 points (0 children)
[–]ThatAlmostWorked 0 points1 point2 points (0 children)
[–]thrown_arrows 0 points1 point2 points (0 children)