How incremental refresh on Materialized view works? - oracle

Say I have a below query which is constructing materialized view(MV)
select * from employee, department where employee.id = department.id and name like '%Andy%'
I have two related questions on How incremental update on MV works internally
1) Say I insert or update any entry either in employee or department table, can I configure increment refresh on MV to be asynchronous of insert/update transaction
or it is mandatory to be synchronous process ?
2)While insert or update , Does oracle evaluate(through transactionl logs) each updated/inserted row and apply the MV query criteria , see if satisfies it . If yes, update or insert the row in MV ?

1) Say I insert or update any entry either in employee or department table, can I configure increment refresh on MV to be asynchronous of insert/update transaction or it is mandatory to be synchronous process ?
If you want to have data available on a materialized view as soon as changes are committed on the base table then you can use ON COMMIT refresh method.
Or if you want to refresh by incrementally applying changes to the materialized view then you can use FAST refresh method. You can do this asynchronously.
2)While insert or update , Does oracle evaluate(through transactionl logas) each updated/inserted row and apply the MV query criteria , see if satisfies it . If yes, update or insert the row in MV ?
It depends upon what kind of refresh method you are using. If you are using FAST or ON COMMIT refresh method then yes, it only applies the changes to the MV which satisfy the criteria defined in the query used to create the MV.

For FAST REFRESH you have to create MATERIALIZED VIEW LOG on base tables you select for the MV. In these materialized view logs Oracle stores updated/inserted/deleted row information. i.e. Oracle does not use the REDO logs as you presumed.
Once all MViews based on your table are refreshed (either by ON COMMIT or manual REFRESH) content of according materialized view logs are truncated.

Related

AUTO-Scynhronize a table based on view - ORACLE DATABASES

I want to ask you if there is a solution to auto-synchronize a table ,e.g., every one minute based on view created in oracle.
This view is using data from another table. I've created a trigger but I noticed a big slowness in database whenever a user update a column or insert a row.
Furthermore, I've tested to create a job schedule on the specified table (Which I wanted to be synchronized with the view), however we don't have the privilege to do this.
Is there any other way to keep data updated between the table and the view ?
PS : I'm using toad for oracle V 12.9.0.71
A materialized view in Oracle is a database object that contains the results of a query. They are local copies of data located remotely, or are used to create summary tables based on aggregations of a table's data. Materialized views, which store data based on remote tables, are also known as snapshots.
Example:
SQL> CREATE MATERIALIZED VIEW mv_emp_pk
REFRESH FAST START WITH SYSDATE
NEXT SYSDATE + 1/48
WITH PRIMARY KEY
AS SELECT * FROM emp#remote_db;
You can use cronjob or dbms_jobs to schedule a snapshot.

Oracle Materialized View: update MVs in the remote db?

I created a fast refresh MV in a remote db by using a syntax like follows:
CREATE MATERIALIZED VIEW MV_TAB1
REFRESH FAST WITH PRIMARY KEY
START WITH SYSDATE NEXT SYSDATE+(5/1440) /* 5 MINUTES */
FOR UPDATE AS
SELECT * FROM TAB1#SOURCE_DB;
Now in the remote db where the MV_TAB1 was created, is it possible to update the MV_TAB1 and keep the update even after the refresh? My testing shows that after each refresh, my update on MV_TAB1 is gone. Is there any way to keep this local update? If yes,how?
Thanks,
Amos
MV_TAB1 is an image of TAB1#SOURCE_DB, so you can't have it in the same time like TAB1 and different to TAB1.
If you update some rows on destination table and then update them in the source, the refresh will overwrite them. If you dont update them in the source they will remain updated ONLY if you use refresh fast. A refresh complete will delete/truncate the remote table and reinsert all rows.
UPDATE: If you want updates on remote table to have priority over the refresh, you can to some tricks:
1) keep the MV as it is and do updates(and inserts) on a sister table with the same DDL. The query, instead of MV, will use both tables, something like:
select nvl(a.key, b.key), decode(a.key, null, b.col, a.col)
from tab1_sister a
full join mv_tab1 b on (a.key = b.key);
2) Add columns to the MV_TAB1(duplicate them, except the key) and do the updates on those columns (it is possible that MV must be with prebuilt table). If the additional columns are completed, use them, otherwise use the original columns updated by the refresh.

Why does a ORA-12054 error occur when creating this simple materialized view example?

ALTER TABLE RECORDINGS ADD PRIMARY KEY (ID);
CREATE MATERIALIZED VIEW LOG ON RECORDINGS TABLESPACE USERS NOLOGGING;
DROP MATERIALIZED VIEW REC_SEARCH_TEST;
CREATE MATERIALIZED VIEW REC_SEARCH_TEST
REFRESH COMPLETE ON COMMIT
AS (
SELECT DISTINCT ID, TITLE FROM RECORDINGS
);
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
Cannot understand what is wrong here, I know that if I take out the DISTINCT clause it works, but why can I not use 'DISTINCT' if I specify 'REFRESH COMPLETE ON COMMIT' which is required.
If I use DISTINCT and REFRESH on demand there is no problem, but these are not the requirements.
Seems like with the addition of the DISTINCT, you've made your view's underlying SQL ineligible for fast refresh, and therefore not able to be used with ON COMMIT (even tho you specify refresh complete instead of refresh fast). From Oracle docs:
The two refresh execution modes are ON COMMIT and ON DEMAND. Depending
on the materialized view you create, some of the options may not be
available. Table 8-4 describes the refresh modes.
Table 8-4 Refresh Modes
ON COMMIT
Refresh occurs automatically when a transaction that modified one of
the materialized view's detail tables commits. This can be specified
as long as the materialized view is fast refreshable (in other words,
not complex). The ON COMMIT privilege is necessary to use this mode.
ON DEMAND
Refresh occurs when a user manually executes one of the available
refresh procedures contained in the DBMS_MVIEW package (REFRESH,
REFRESH_ALL_MVIEWS, REFRESH_DEPENDENT).
The same document link has a list of restrictions for fast refresh as well.
"Perhaps the example isn't the best, because I want to expand the view
to a more complicated query that will require a distinct keyword,
right now I am just trying to get it working on a basic level. "
The DISTINCT is the cause of the ORA-12054.
SQL> CREATE MATERIALIZED VIEW REC_SEARCH_TEST
REFRESH COMPLETE ON COMMIT
AS (
SELECT DISTINCT empno, ename FROM emp
)
/
2 3 4 5 6
SELECT DISTINCT empno, ename FROM emp
*
ERROR at line 4:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
Elapsed: 00:00:01.14
SQL> SQL>
SQL> CREATE MATERIALIZED VIEW REC_SEARCH_TEST
REFRESH COMPLETE ON COMMIT
AS (
SELECT empno, ename FROM emp
)
/
2 3 4 5 6
Materialized view created.
Elapsed: 00:00:02.33
SQL>
Why not start with a something that works? Remove the DISTINCT. Get your MView working. Then complicate it later when it becomes necessary.
Although, as you already know you cannot use a DISTINCT you will have to revise either your query's logic or your refresh strategy.
The important thing to note about the question is that it is not about fast refresh, but complete refresh. Thus, there is no logical reason that the usual restrictions for fast refresh on commit should apply, except the one that all referenced objects must be local.
The "refresh complete on commit is a relatively new feature, so the best answer to the "why" question is probably "Oracle has not yet implemented this fully, please check future versions of Oracle Database". Not very useful, but true...

Is there a way to query the changes made by a materialized view fast refresh in Oracle?

Say that you have two Oracle databases, DB_A and DB_B. There is a table named TAB1 in DB_A with a materialized view log, and a materialized view named SNAP_TAB1 in DB_B created with
CREATE SNAPSHOT SNAP_TAB1
REFRESH FAST
AS SELECT * FROM TAB1#DB_A;
Is there a way to query in DB_B the changes made to SNAP_TAB1 after each call to fast-refresh the materialized view ?
DBMS_SNAPSHOT.REFRESH( 'SNAP_TAB1', 'F' );
In DB_A, prior to the refresh, you can query the materialized view log table, MLOG$_TAB1, to see which rows have been changed in TAB1. I'm looking for a way to query in DB_B, after each refresh, which rows have been refreshed in SNAP_TAB1.
Thanks!
I think the lines below work with prebuilt table:
You can add a column in the table SNAP_TAB1.
For inserts You can put it on default sysdate => for every insert you'll have the timestamp of the insert.
For updates you can use a trigger. Because the column is not involved in the Materialized View, updating the column with the trigger won't be a problem.
Probaly better, with the trigger you can use an unique id to store in that column, incremented before every new refresh.(Obtaining the unique id may have different aproaches.)
Obviously, you can't track deletes with this idea.

Refreshing Materialzed View in Oracle

I have created materialized view (MV) on a table which is updated once in a month..
Do we have any automatic way to refresh my MV...
I mean how refresh of MV is done is it manual or
Automatic how frequent we can do????
like can i use Trigger for it..??
I am using Oracle9i on PL/SQL developer
Thanks
You can refresh the view manually if you want
execute DBMS_SNAPSHOT.REFRESH( 'MAT_VIEW','OPTION');
Where the OPTION parameter could be
F, f Fast Refresh
C, c Complete Refresh
A Always perform complete refresh
? Use the default option
The automatic refresh rate are supplied when you create the materialized view
CREATE MATERIALIZED VIEW MAT_VIEW
REFRESH FAST START WITH SYSDATE
NEXT SYSDATE + TIME_INTERVAL --
WITH PRIMARY KEY
AS SELECT * FROM TABLE;
Remember to create a log for the table if FAST START are used.
I recomend you the following link about Materialized View. It has a lot of info about this topic: http://www.dba-oracle.com/art_9i_mv.htm

Resources