Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redefine materialized view with no downtime

I have a materialized view that I need to redefine the SQL for. We have an external system that hits the view over a db link, and the monster view takes 5 minutes to refresh the data in the view. The only way I know how to redefine the SQL for a view is to drop it and recreate it, but it would be very bad if the external system couldn't find the table, or it didn't have a complete data set. I need to have as little downtime as possible.

Is there any way to do this natively or more elegantly than:

  1. Create public synonym for materialized view and make everything that uses the view use the synonym instead.
  2. Create new materialized view with new SQL
  3. Change the synonym to point to the new view
  4. Drop the old view.

I've got code to do this dynamically but it is getting really ugly. It seems like there should be a better way to handle this.

like image 644
bitwes Avatar asked Aug 06 '13 16:08

bitwes


People also ask

Can you update a materialized view?

The data in the materialized view remains unchanged, even when applications make changes to the data in the underlying tables. To update the data in a materialized view, you can use the REFRESH MATERIALIZED VIEW statement at any time.

How do you refresh a materialized view daily?

you can just use ALTER to do this - it'll create a job for you: ops$tkyte%ORA10GR2> create materialized view mv 2 refresh complete 3 as 4 select * from t; Materialized view created.

How do you automatically refresh a materialized view?

You can also use the AUTO REFRESH clause to refresh materialized views automatically. For more information about creating materialized views, see CREATE MATERIALIZED VIEW. You can turn on autorefresh for a current materialized view by using ALTER MATERIALIZED VIEW.


1 Answers

Oracle has a build in solution for that. Keep in mind that the mview declaration is separate from that of the table.

The original mview

create materialized view mv1 as select dept , count(*) as cnt from scott.emp;

we want to change the declaration so that only dept over 5 will be calculated

drop materialized view mv1 preserve table;

notice the PRESERVE TABLE clause - the table mv1 is not droped - only the mview layer.

desc mv1

now we create the mview with a different query on top of the existing table

create materialized view mv1 on prebuilt table as 
  select dept , count(*) as cnt from scott.emp where dept > 5;

notice the on prebuilt table clause. the mview is using the existing object.

exec dbms_mview.refresh_mview('mv1');
like image 95
haki Avatar answered Nov 15 '22 05:11

haki