I have an insert...select query where the select is a join between a table with one billion rows (although there is a where clause on an indexed column that restricts it to "only" 300 million), a table with 30 million rows, and a table with about 100,000 rows, where the result is about 20 rows. When I first ran it, it took about 2 hours. I added a Parallel hint, and explain plan showed that it was being used (and v$session showed that I had about 30 additional connections while it ran). but not it takes four hours.
Is there a reason parallel processing would cause a query to run slower?
insert /*+ append */ into employees_by_age_group
(
pay_plan
, age_range
, pay_level
, fy
, employee_count
)
select /*+ parallel */
emp.pay_plan
, to_char(d.min_age) || '-' || to_char(d.max_age) as age_range
, emp.pay_level
, pay.fy
, count(pay.employee_id) as employee_count
from
(
select /*+ index(pay_info pay_info_index_on_site) */
employee_id
, extract(year from (dte_ppe_end + 92)) as fy
, count(employee_id) as num_recs
from pay_info
where extract(month from dte_ppe_end) = 10
and extract(day from dte_ppe_end) between 14 and 27
and substr(pay_type, 1, 1) IN ('A', 'B', 'C')
and site like 'Z%'
group by employee_id, extract(year from (dte_ppe_end + 92))
) pay
join
(
select employee_id
, pay_plan
, pay_grade
, pay_step
, file_date
from
(
select /*+ index(employee_info employee_info_index_on_site) */
employee_id
, pay_level
, file_date
, max(file_date)
over (partition by extract(year from (file_date + 61)))
as last_file_date
from employee_info
where site like 'Z%'
)
where file_date = last_file_date
) emp
on (
emp.employee_id = pay.employee_id
and extract(year from emp.file_date) = pay.fy - 1
)
join (
select employee_id
, dob
from (
select employee_id
, date_birth
, row_number() over (partition by employee_id order by date_file desc) as r
from employee_birthdates
where site like 'Z%'
)
where r = 1
) dob
on dob.employee_id = pay.employee_id
join
(
select 20 as min_age, 24 as max_age from dual
union all select 25 as min_age, 29 as max_age from dual
union all select 30 as min_age, 34 as max_age from dual
union all select 35 as min_age, 39 as max_age from dual
union all select 40 as min_age, 44 as max_age from dual
union all select 45 as min_age, 49 as max_age from dual
union all select 50 as min_age, 54 as max_age from dual
union all select 55 as min_age, 59 as max_age from dual
union all select 60 as min_age, 64 as max_age from dual
union all select 65 as min_age, 69 as max_age from dual
union all select 70 as min_age, 74 as max_age from dual
union all select 75 as min_age, 79 as max_age from dual
union all select 80 as min_age, 84 as max_age from dual
union all select 85 as min_age, 89 as max_age from dual
union all select 90 as min_age, 94 as max_age from dual
union all select 95 as min_age, 99 as max_age from dual
) d
group by emp.pay_plan, d.min_age, d.max_age, emp.pay_level, pay.fy;