EXPLAIN: I'm running this SQL that takes >6 hours to run and I'm trying to see if this SQL code (please see below) could be made better. I realize that there are multiple joins from various tables, so it is a bit cumbersome. It should be noted that there are ~2 million rows. Any suggestions are much appreciated. THANKS!!!!
PLAN: Should I deconstruct this SQL into multiple tables and then union it all together? OR Is there a better approach? Sorry, I'm a bit lost in how to approach this problem b/c I was recently informed that I need to run this SQL everyday with only 1 thread.
select /*+ ordered full(t) full(s) full(l) full(b) parallel(72)*/
t.column1
,b.column1
,to_date(t.column2,'YYYYMMDD')
,to_date(b.column2,'YYYYMMDD')
,cr.column1
,cr.column2
,s.column1
,t.column3
,t.column4
,b.column4 as paid_clm_unique_key
,CASE WHEN t.column5 IN ('ASTR','HIHI','HITR','HOTR','PHTR') THEN 'YES'
WHEN t.column5 IN ('HIOI','HOHE','HOHO','HOHS','HOOO','HOOS') THEN 'NOPE'
ELSE 'MAYBE' END type_cd
,t.column6
,m.column6
,last_day(to_date(t.column7,'YYYYMMDD'))
,last_day(to_date(t.column8,'YYYYMMDD'))
,S.column8
,case when substr(S.column8,1,4) = '0999' then 'PREPAY' else 'OTHER' END REASON_CD
,S.column9
,' 'column10
,case when t.column9 = 'EM' then substr(l.column1,1,3) else substr(l.column1,3,5) end code1
,case when t.column9 = 'EM' then substr(l.column6,1,3) else substr(l.column6,3,5) end code2
,t.column10
,nvl(t.column11,'NVAL')
,t.column12
,t.column13
,t.column14
,t.column15
,nvl(t.column16,'NVAL')
,t.column7
,t.column17
,cr2.column17
,nvl(b.column17,0)
,nvl(b.column18,0)
,case when b.column1 is null then t.column17
when sum(b.column17) over (partition by t.column1) = 0 then (t.column17/count(b.column1) over (partition by t.column1))
else (b.column17/sum(b.column17) over (partition by t.column1)) * t.column17 end as d_amt_wdup
,t.column17/(case when sum(t.column17) over (partition by b.column1) = 0 then count(t.column1) over (partition by b.column1)
else sum(t.column17) over (partition by b.column1) end) * nvl(b.column17,0) as p_amt_wdup
,t.column17/(case when sum(t.column17) over (partition by b.column1) = 0 then count(t.column1) over (partition by b.column1)
else sum(t.column17) over (partition by b.column1) end) * nvl(b.column18,0) as p_n_amt_wdup
,case when row_number() over (partition by t.column10,nvl(t.column11,'NVAL'),t.column14
,t.column15,nvl(t.column16,'NVAL'),t.column17,b.column1
order by t.column7 desc,t.column1 desc) = 1 then 'N' else 'Y' end as duplicate
from TABLE1 t
join TABLE2 m on t.column20 = m.column20
join TABLE3 cr on m.column6 = cr.column20
join TABLE4 s on t.column1 = s.column20
join TABLE5 l on t.column1 = l.column20
left join TABLE1 b on b.column2 >= to_char(add_months(last_day(trunc(sysdate)),-13),'YYYYMMDD') --rolling 13 mos.
and b.column20 in ('EM','LV')
and t.column10 = b.column21
and nvl(t.column11,'NVAL') = nvl(b.column22,'NVAL')
and t.column15 = b.column23
and t.column3 = b.column24
and t.column14 = b.column25
and nvl(t.column16,'NVAL') = nvl(b.column26,'NVAL')
and t.column27 < nvl(b.column27,'99990101') ---paid at least 1 day after rejected
and t.column7 <= nvl(t.column28,'99990101') --makes sure paid not received before rejected
and t.column2 <= nvl(b.column2,'99990101') --paid mth after/equal to rejected mth
and nvl(b.column2,'99990101') >= nvl(b.column29,'00010101') --filter out future CCCC month
and b.column30 = 'C'
and b.column17 <> 0
left join TABLE2 m2 on b.column31 = m2.column31
left join TABLE3 cr2 on m2.column32= cr2.column32
where t.column2 >= to_char(add_months(last_day(trunc(sysdate)),-13),'YYYYMMDD') --rolling 13 mos.
and s.column40 >= to_char(add_months(last_day(trunc(sysdate)),-13),'YYYYMMDD') --rolling 13 mos.
and l.column40 >= to_char(add_months(last_day(trunc(sysdate)),-13),'YYYYMMDD') -- rolling 13 mos.
and t.column9 in ('EM','LV') and s.column50 in ('EM','LV') and l.column50 in ('EM','LV')
and t.column17 <> 0
and s.column60 not in ('Y','S','D')
and t.column60 = 'R'
group by t.column61
,b.column1
,t.column17
,t.column62
,b.column17
,b.column18
,t.column3
,to_date(t.column2,'YYYYMMDD')
,to_date(b.column2,'YYYYMMDD')
,t.column2
,cr.column1
,cr.column62
,s.column1
,t.column4
,CASE WHEN t.column5 IN ('ASTR','HIHI','HITR','HOTR','PHTR') THEN 'YES'
WHEN t.column5 IN ('HIOI','HOHE','HOHO','HOHS','HOOO','HOOS') THEN 'NOPE'
ELSE 'MAYBE' END
,t.column63
,m.column6
,t.column12
,t.column13
,cr2.column17
,last_day(to_date(t.column7,'YYYYMMDD'))
,last_day(to_date(t.column8,'YYYYMMDD'))
,S.column8
,case when substr(S.column8,1,4) = '0999' then 'PREPAY' else 'OTHER' END
,S.column9
,case when t.column9 = 'EM' then substr(l.column1,1,3) else substr(l.column1,3,5) end
,case when t.column9 = 'EM' then substr(l.column6,1,3) else substr(l.column6,3,5) end
,t.column10
,nvl(t.column11,'NVAL')
,t.column14
,t.column15
,nvl(t.column16,'NVAL')
,t.column7
,b.column4