Thanks for the question, Sameer.
Asked: March 22, 2017 - 4:53 pm UTC
Last updated: April 03, 2017 - 12:48 am UTC
Version: 11.2.0.4 Enterprise
Viewed 10K+ times! This question is
You Asked
Hello,
All of our MV's are built as completely refresh-able, on-demand, with nologging, as shown below:-
CREATE MATERIALIZED VIEW mv_name
NOLOGGING
TABLESPACE "DATA_SPACE"
USING INDEX TABLESPACE "INDEX_SPACE"
REFRESH ON DEMAND
COMPLETE
AS
--SELECT Text as an example only (this SQL query Text gets populated dynamically from either a CLOB column or from a CLOB procedure's IN parameter with SELECT always having compiler hints as shown:
SELECT /*+ PARALLEL(8) NOLOGGING */ *
FROM tb_name_1
UNION
SELECT /*+ PARALLEL(8) NOLOGGING */ *
FROM tb_name_2
;
Once the MV is created and stats gathered, the Analysts begin using the MV and sometimes, depending on the performance and reporting needs, we may have to add BITMAP, UNIQUE and NON-UNIQUE indexes on multiple columns on the MV. Each MV may have a different refresh schedule depending on the data-source's own refresh schedule.
The main objective is to build a "lean" refresh operation, as much as possible, which will hopefully, result into refreshes that will take the least amount of time (as much as we can even though some refreshes will take longer due to the nature of the SQL query, etc.).
Upon reading the 11.2 documentation for DBMS_MVIEW.REFRESH, it mentions that setting the parameter atomic_refresh => FALSE will take care of (a) disabling, (b) re-building, and (c) computing stats for UNIQUE indexes ONLY.
Does this mean that for all "other" index types present on the MV, like BITMAP and NON-UNIQUE, I have to manually:-
(a) Disable all BITMAP and NON-UNIQUE indexes (ignoring UNIQUE indexes) before running DBMS_MVIEW.REFRESH,
(b) Run the DBMS_MVIEW.REFRESH with parameters method => 'C' and atomic_refresh => FALSE,
(c) Rebuild all BITMAP and NON-UNIQUE indexes (hoping the UNIQUE indexes will be re-built in the step above),
(d) Gather Table Stats that will compute stats for both the Table as well as all the Indexes.
Appreciate any advise :)
and Chris said...
No, Oracle Database refreshes non-unique indexes and gather stats on them too with non-atomic refreshes:
create table t2 ( x , y ) as
select rownum x, mod(rownum, 5) y from dual connect by level <= 1000;
create table t1 ( x , y ) as
select rownum x, mod(rownum, 3) y from dual connect by level <= 1000;
create materialized view mv_name
refresh on demand
as
select t1.* from t1
union
select t2.* from t2;
create index iy on mv_name(y);
select status, num_rows from user_indexes
where index_name = 'IY';
STATUS NUM_ROWS
VALID 1,800
insert into t1
select rownum+1000 x, mod(rownum, 3) y from dual connect by level <= 1000;
insert into t2
select rownum+1000 x, mod(rownum, 5) y from dual connect by level <= 1000;
commit;
exec dbms_mview.refresh('mv_name', atomic_refresh => false);
select status, num_rows from user_indexes
where index_name = 'IY';
STATUS NUM_ROWS
VALID 3,600
select count(*) from mv_name;
COUNT(*)
3,600
In terms of making your refresh faster, it's worth investigating if you can go for regular fast refreshes. You have to go for complete refreshes with union. But you can fast refresh with union all. (Just make sure you add a marker column:
https://jonathanlewis.wordpress.com/2016/07/12/union-all-mv/ )
So you could:
- Create a fast refresh union all MV
- A complete refresh MV on top of this returning the distinct rows
This may help if the intersection of the two tables is "small". If so, the distinct MV will have much less data to process => it'll be faster.
Rating
(1 rating)
Is this answer out of date? If it is, please let us know via a Comment