Skip to Main Content
  • Questions
  • Fast refreshable mviews with JOIN operators - using PK?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Raul.

Asked: January 16, 2023 - 6:17 am UTC

Last updated: January 19, 2023 - 12:02 am UTC

Version: 19.17

Viewed 1000+ times

You Asked

I have a fast refreshable materialized view question.
At the moment, the issue is, I cannot do any maintenance on mview base tables (e.g. tables that have mview log defined on them).
Our materialized views consist of joins to join multiple tables together, and due to that mview log must be created with rowid (not possible via PK). Now the problem that thw rowid opposes - whenever I move base table rows (whatever method I use, table redefinition perhaps), then my mviews are not fast refreshable any more, and since complete refresh takes more time to just drop and recreate it, then I have used drop/recreate approach, but this does mean downtime, since mview objects are missing from data dictionary for a certain amount of time.

I am curious, will there (23c) be any materialized view improvements compared to 19c ?
Curious about mview fast refresh using PK when mview consists JOIN operators. At the moment, fast refresh is only possible with rowid's when mview consists JOIN operators.

Or, if there is no such improvements done yet, what are future views regarding this issue - will there be hope that somedays this will be done. I mean in technical point of view, is it really tht difficult to implement. I mean the PK vs rowid - yes these both are different things, but share the same purpose. With PK, you only have that extra index access time cost in addition compared to rowid.

Raul

and Chris said...

I'm unclear exactly what issue you're hitting here.

While you're correct you need the ROWIDs, materialized views can continue to fast refresh across some ROWID-changing operations

For example, moving a table (on 19.11):

create table t1 (
  t1_pk int primary key,
  c1 int,
  c2 int
);

create table t2 (
  t2_pk int primary key,
  t1_fk references t1,
  c1 int,
  c2 int
);

create materialized view log 
  on t1 with rowid, primary key,
  sequence
  including new values;
  
create materialized view log 
  on t2 with rowid ( t1_fk ),
  sequence
  including new values;
  
create materialized view mv 
refresh fast on commit
as
  select count(*) c
  from   t1, t2
  where  t1_pk = t1_fk;
  
insert into t1 values ( 1, 1, 1 );
insert into t2 values ( 1, 1, 2, 2 );
insert into t2 values ( 2, 1, 3, 3 );
commit;
select * from mv;
/*
         C
----------
         2
*/
select rowid from t2;
/*
ROWID             
------------------
AAAsfpAAcAAACDuAAA
AAAsfpAAcAAACDuAAB
*/

alter table t2 
  move online;

select rowid from t2;
/*
ROWID             
------------------
AAAsfzAAcAAAv97AAA
AAAsfzAAcAAAv97AAB
*/

insert into t2 values ( 4, 1, 3, 3 );
commit;
select * from mv;
/*
         C
----------
         3
*/
select last_refresh_type, staleness 
from   user_mviews
where  mview_name = 'MV';
/*
LAST_REF STALENESS          
-------- -------------------
FAST     FRESH  
*/


whatever method I use, table redefinition perhaps

DBMS_Redefinition is one case where this could be a problem while the refresh is running:

https://docs.oracle.com/en/database/oracle/oracle-database/19/dwhsg/refreshing-materialized-views.html#GUID-1B4FCFD7-C08E-42BC-BFB6-68D053B8E0D5

Are you actually planning this, or is this just a fear you might want to do it someday? If it's the latter, I'd put that in the "worry about it when it happens" category!

since complete refresh takes more time to just drop and recreate it

Have you tried non-atomic refreshes?

By default, complete refreshes are atomic, which do DELETE+INSERT. The DELETE step can take a long time on huge MVs.

Non-atomic refreshes do TRUNCATE+INSERT instead. TRUNCATE is "instant", so this should be significantly faster and close to the performance of DROP+CREATE.

With non-atomic refreshes there will be a period while the MV appears empty. So you may still want/need downtime to do this; the objects still exist though so the app will still function. So you may be able to leave it online with data disclaimers during the refresh.

Rating

  (2 ratings)

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

Comments

Raul, January 16, 2023 - 3:01 pm UTC

Hi

No we are not planning it. It has been on production for years now.
And the issue is - the DDL that need to be done on the base tables, for example let's say DROP'ing a column that is not present on mview.

DROP'ing a column cannot be done online (locking issue), whereas dbms_redefinition can. So for all the DDL's that can be done using dbms_redefinition instead, I have gone that approach. But for the mview base tables, it is not possible.

Another thing is yes fragmentation - I have used dbms_redefinition as well for that.

Regards
Raul
Raul
Chris Saxon
January 17, 2023 - 4:38 pm UTC

So again, are you actually planning to DROP columns or is this "just in case"?

Another thing is yes fragmentation

I'm unclear what you're referring to by this; surely you could use an online table move?

Raul, January 18, 2023 - 3:51 pm UTC

Mviews have been in use for years now - this should be clear by now, that it is not "just in case" type of thing.

There have been numerous cases where there is a need to drop a column.
These are real world situations that I ma referring here.

So again, my question is, is there a plan to make "mviewlog with PK and mview query with JOIN operator" possible in near future..?

Regards
Raul

More to Explore

Design

New to good database design? Check out Chris Saxon's full fundamentals class.