In this example, I am creating a materialized view to support queries against a table with 20 million rows, which are looking at the maximum sequence number within a range of dates.
Oracle describes the benefits of Materialized views like this:
"One of the major benefits of creating and maintaining materialized views is the ability to take advantage of query rewrite, which transforms a SQL statement expressed in terms of tables or views into a statement accessing one or more materialized views that are defined on the detail tables."
Since I want the materialized view to be refreshed every time a new row is commited to the base table, I need to specify that the mview should use "fast refresh".
First, create a materialized view log to store changed rows in the base tables that your materialized views are built on. This is required when using FAST REFRESH:
CREATE MATERIALIZED VIEW LOG ON DATE_TO_SEQNO TABLESPACE DATA1 CACHE ENABLE ROW MOVEMENT WITH ROWID (SEQNO, RDATE) INCLUDING NEW VALUES;
Then, create the materialized view. Query rewrites are disabled by default, so it must be explicitly stated:
CREATE MATERIALIZED VIEW SEQ_AGGR_INFO SEGMENT CREATION IMMEDIATE TABLESPACE DATA1 CACHE ENABLE ROW MOVEMENT ROW STORE COMPRESS ADVANCED BUILD IMMEDIATE REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS select RDATE, count(SEQNO) as antall, max(SEQNO) as makssekvens from DATE_TO_SEQNO group by dato order by 1, 2;
Verify the mview's existence:
SELECT mview_name,rewrite_enabled,refresh_mode,refresh_method, last_refresh_type, last_refresh_date,last_refresh_end_time,staleness,compile_state FROM USER_MVIEWS;
MVIEW_NAME | REWRITE_ENABLED | REFRESH_MODE | REFRESH_METHOD | LAST_REFRESH_TYPE | LAST_REFRESH_DATE | LAST_REFRESH_END_TIME | STALENESS | COMPILE_STATE |
---|---|---|---|---|---|---|---|---|
SEQ_AGGR_INFO | Y | COMMIT | FAST | COMPLETE | 18.01.2019 13:58:24 | 18.01.2019 13:58:24 | FRESH | VALID |
Verify the mview log's existence:
SELECT master,log_table,rowids, primary_key,filter_columns, include_new_values FROM USER_MVIEW_LOGS;
MASTER | LOG_TABLE | ROWIDS | PRIMARY_KEY | FILTER_COLUMNS | INCLUDE_NEW_VALUES |
---|---|---|---|---|---|
DATE_TO_SEQNO | MLOG$_DATE_TO_SEQNO | YES | NO | YES | YES |
The following query will now use the materialized view, due to the QUERY REWRITE directive used in the creation of the mview:
var B1 VARCHAR2(10); EXEC :B1 := to_date('01.01.2018','dd.mm.yyyy'); set lines 200 set autot on set timing on select max(seqno) from DATE_TO_SEQNO where rdate = :B1;
The explain plan verifies it:
MAX(SEKVENSNUMMER) ------------------ 18580449 Elapsed: 00:00:00.05 Execution Plan ---------------------------------------------------------- Plan hash value: 1856567295 -------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 14 | 243 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 14 | | | |* 2 | MAT_VIEW REWRITE ACCESS FULL| SEQ_AGGR_INFO | 1 | 14 | 243 (0)| 00:00:01 | -------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter("SEQ_AGGR_INFO"."RDATE"=:B1)
To drop the materialized view and its log object:
drop materialized view log on DATE_TO_SEQNO; drop materialized view SEQ_AGGR_INFO;
Sources:
Create Materialized View Log
Create Materialized view
Datawarehousing guide
No comments:
Post a Comment