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
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 perhapsDBMS_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 itHave 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.