Skip to Main Content
  • Questions
  • PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Valli.

Asked: May 22, 2017 - 4:09 pm UTC

Last updated: May 24, 2017 - 12:46 am UTC

Version: 12c

Viewed 10K+ times! This question is

You Asked

Fact table with over 250M rows.

Data in question is around 100M. I am running a quarterly aggregate to calculate simple weighted averages at different grains.

Query I am using is pretty simple and straightforward.
However, when executed against the entire data set, I get the below error:


ORA-00039: error during periodic action
ORA-04036: PGA memory used by the instance exceeds PGA_AGGREGATE_LIMIT
00039. 00000 - "error during periodic action"
*Cause: An unexpected error occurred while executing a periodically invoked
action.
*Action: Check the error stack for detailed error information.

In the actual environment, the datasource is a view but no parallelism defined.

Question: Can you please explain in what conditions this error would come about?

For running aggregates against 100M rows, is this the right approach? (Using Union?)
Is there a better way to do this kind of aggregation?

Please see the query below and the Live SQL Link attached:

select 'All' as Grain,'ALL' as Location,'ALL' as Department
,sum(salary*weight)/sum(weight) as Salary_Avg
,sum(bonus*weight)/sum(weight) as Bonus_Avg
,sum(commission*weight)/sum(weight) as Commission_Avg
,sum(term*weight)/sum(weight) as Term_Avg
from employee
union
select 'Location' as Grain,location,'ALL' as Department
,sum(salary*weight)/sum(weight) as Salary_Avg
,sum(bonus*weight)/sum(weight) as Bonus_Avg
,sum(commission*weight)/sum(weight) as Commission_Avg
,sum(term*weight)/sum(weight) as Term_Avg
from employee
group by location
union
select 'Department' as Grain,'ALL' as Location,department
,sum(salary*weight)/sum(weight) as Salary_Avg
,sum(bonus*weight)/sum(weight) as Bonus_Avg
,sum(commission*weight)/sum(weight) as Commission_Avg
,sum(term*weight)/sum(weight) as Term_Avg
from employee
group by department



with LiveSQL Test Case:

and Connor said...

Those three queries look to be mutually exclusive, ie, its impossible to have overlap (simply due to the Grain column).

A UNION of A and B does:

- get A
- get B
- remove entries that occur in both A and B so we dont duplicate them

That last step means a big sorting operation.

So change the UNION to UNION ALL and see how you go.

Even so, check your PGA_AGGREGATE_LIMIT to make sure it is set sensibly for the database/machine.

Is this answer out of date? If it is, please let us know via a Comment