Reputation: 13
I am trying write a query to run an update on a table with around 1 million records, the query is expected to update around 10000 records. The query takes around 10 minutes to complete which is too slow for my requirement. below is the query
update ABC t1
set amount_pct = (select (t1.amount / b.masteramt) * 100
from (select id, mstr_group, year, month, sum(amount) as masteramt
from ABC where id = 110
group by id, mstr_group ,year, month) b
where b.id = t1.id and b.mstr_group = t1.mstr_group
and b.year *100 + b.month = t1.year * 100 + t1.month AND b.masteramt != 0)
where t1.id = 110
I tried creating a materialized view and used that instead of the original table in the select query Query for materialized code
CREATE MATERIALIZED VIEW mv1 AS
select id, mstr_group, year, month, sum(amount) as masteramt
from ABC
group by id, mstr_group , year, month
and re wrote the above query as
update ABC t1 set amount_pct =
(select (t1.amount / b.masteramt) * 100 from
(select * from mv1) b
where b.id = t1.id and b.mstr_group = t1.mstr_group
and b.year *100 + b.month = t1.year * 100 + t1.month AND b.masteramt != 0)
where t1.id = 110
the query was faster than the original query but still took around 7 minutes to complete . Is there a way to modify this query to run any quicker ? I am using oracle 11g and the table ABC has indexes on id and mstr_grp
Upvotes: 1
Views: 640
Reputation: 1269913
I don't think you need the group by
in the subquery. Something like this should work:
update ABC t1
set amount_pct = (select t1.amount / sum(b.masteramt) * 100
from ABC b
where b.id = 110 and
b.id = t1.id and
b.mstr_group = t1.mstr_group and
b.year * 100 + b.month = t1.year * 100 + t1.month
)
where t1.id = 110;
Then, you want an index on (id, mstr_group, year, month)
.
Upvotes: 1