You are on page 1of 18

Oracle 10g Materialized View

Enhancements, Part 1
By Jim Czuprynski
Synopsis. Oracle 10g Release 2 (10gR2) has improved the effectiveness and speed of
materialized view refreshes, something that is becoming especially important in increasingly
complex data warehouses and data mart environments. This article the first in a series
demonstrates several new features of materialized views in Oracle 10gR2, including
enhancements to join-only materialized views, new optimizer hints for improved QUERY
REWRITE analysis, and improved materialized view debugging tools.
Materialized views have been available in one form or another since before Oracle 8i, when
they were called snapshots, and they can appear somewhat mysterious if you havent yet
encountered one because your current database environment hasnt yet demonstrated a
need (e.g. data warehousing). The simplest way to think of a materialized view is that its a
view that references an underlying table, and that table contains data that can be refreshed
automatically on a periodic scheduled basis, refreshed manually by a call to an Oracle
supplied package called DBMS_MVIEW, or even decide to refresh itself whenever rows in
other source tables change.
The true strength of a materialized view becomes extremely apparent in a data warehouse,
a data mart, or even a hybrid environment. For example, I can build a materialized view
that describes which employees are currently assigned to various roles within the companys
hierarchical organization structure; when an employee changes roles, or a new employee is
added to the hierarchy, the materialized view will detect these modifications and thus decide
to refresh itself.
Materialized Join View (MJV) Enhancements
Oracle 10gR2 has finally removed some limits imposed as far back as Oracle 9i on the
performance and flexibility of materialized view refresh mechanisms. One previous limitation
that has been removed is that materialized views that contained joins only also known as
MJVs can now be refreshed quickly and automatically. However, there are still a few
limitations and restrictions on MJVs:
ROWIDs Required for Fast Refresh. If the FROM clause of the MJV does contain more
than one table, then every table in the MJV must specify a ROWID column in the SELECT
list, and the materialized view logs for the MJV must also contain the ROWID for those
tables.
View Merging Must Be Permitted. If the MJV contains any named or inline views, then
Oracle must be permitted to perform view merging; once view merging is complete, the
resulting materialized view must satisfy all requirements for fast refresh as mentioned
previously.
Remote Tables Must Be From Same Site. An MJV is now permitted to contain references
to remote tables, which are tables that are accessed via a public or private database link. If
the FROM clause of the MJV does reference any remote tables, then all the tables in the

FROM clause must be located at the same site. Also, note that the ROWID rules mentioned
above also hold true if the MJV is to be fast-refreshed.
Listing 1.1 shows sample code that demonstrates how to create a materialized join view
and its required materialized view logs to take advantage of these new features while still
hewing to the aforementioned restrictions.
Improvements to Materialized View Execution Plan Debugging
One of the more trying tasks Ive faced when stepping into the role of development DBA is
attempting to tune an errant query that I fully expected Oracle should have rewritten to use
a materialized view. In other words, if I create a query against the tables in the materialized
view that returns the same result set that the materialized view will return, Oracle should
execute the query against the materialized view instead of those base tables. Since the
materialized view is usually much smaller in size than the base tables, this means that fewer
resources will be used to return the results to the query.
However, in many cases Oracle may simply appear to refuse to rewrite a query against a
materialized view. There are several reasons that this may occur, but they can be esoteric
and difficult to debug in a timely fashion. Fortunately, Oracle 10g now provides several new
tools and features to help resolve query rewrite issues:
ENABLE_QUERY_REWRITE Defaults to TRUE. I cant count the number of times I have
helped a developer to debug a materialized view that wouldnt rewrite, only to find the
developer had forgotten to set the ENABLE_QUERY_REWRITE initialization parameter to
TRUE on her database. In Oracle 10g, this parameter is set to TRUE by default; it had been
FALSE by default in earlier releases.
REWRITE_OR_ERROR Hint. Since I expect a query that is executed against a
materialized view to be rewritten, it would be nice to have Oracle tell me when a QUERY
REWRITE operation has failed unexpectedly. Oracle 10g provides a new optimizer hint
called REWRITE_OR_ERROR that will return an ORA-30393 error whenever the optimizer
determines that query cannot be rewritten. I can then trap this error as a named exception
and proceed to notify the appropriate developer or DBA so that the issue can be
investigated and resolved.
EXPLAIN PLAN Upgrades. Finally, Oracle 10g at last corrects a minor but nonetheless
important discrepancy in the contents stored in PLAN_TABLE, the table that is necessary
for capturing and retaining information from an EXPLAIN PLAN FOR STATEMENT
command. When a querys access plan can utilize a materialized view instead of one or
more base tables, Oracle 10g now properly records this fact by labeling the access path as a
MATERIALIZED VIEW. (Prior releases will display the access path as a normal TABLE hint
instead.)
Listing 1.2 shows two example queries that access the new materialized join view created
in Listing 1.1, and the resulting query plans that are produced. Note that Im using the
DBMS_XPLAN.DISPLAY procedure to create a PL/SQL collection that is then cast into a
TABLE format so that I can issue a SELECT statement against it to view the EXPLAIN
PLAN output. This is now Oracles suggested method for formatting access plan
information.

This listing also shows what happens when I apply the REWRITE_OR_ERROR hint on a
simple query that uses almost all of the columns in the HR.MJV_LOC_DEPT_EMPS
materialized view. Because the query references the STATE_PROVINCE column in the
HR.LOCATIONS table, the query cannot be rewritten, and therefore generates an ORA30393 error.
Demystifying QUERY REWRITEs With DBMS_MVIEW
Yet another valuable tool for debugging failed or poorly performing query rewrite operations
is Oracles DBMS_MVIEW.EXPLAIN_REWRITE procedure. This procedure populates a
special table named REWRITE_TABLE that will contain detailed information about how a
query rewrite is operating. Oracle 10g has added several new columns to REWRITE_TABLE
to facilitate deeper analysis of why a query failed to rewrite, including information on the
relative costs of the original vs. rewritten SQL.
These new MV debugging features are amply demonstrated in Listing 1.3, which shows
how to populate REWRITE_TABLE when a query rewrite operation performs sub-nominally.
Note that I executed the utlxrw.sql script (found in $ORACLE_HOME/rdbms/admin) to
create REWRITE_TABLE before executing DBMS_MVIEW.EXPLAIN_REWRITE to
populate the table.
Listing 1.4 shows one additional new debugging tool, DBMS_MVIEW.EXPLAIN_MVIEW.
This new procedure analyzes all potential capabilities of a selected materialized view and
returns a list of those operations (e.g., FAST REFRESH) that the materialized view will
currently support. As with DBMS_MVIEW.EXPLAIN_REWRITE, note that I had to execute
the utlxmv.sql script (also found in $ORACLE_HOME/rdbms/admin) to create the
MV_CAPABILITIES table before executing DBMS_MVIEW.EXPLAIN_MVIEW to populate
the table.
Proactively Tuning MVs Using DBMS_ADVISOR.TUNE_MVIEW
Even though these new tools and features are helpful for honing in on exactly why queries
against an MV are not triggering query rewrite operations, what Ive hoped for is a method
to perform proactive tuning of MVs. The good news is that Oracle 10g provides a new
Advisor task called DBMS_ADVISOR.TUNE_MVIEW to which I can submit the text of a
proposed MV for scrutiny.
Once I have submitted an Advisor task for scrutiny, DBMS_ADVISOR.TUNE_MVIEW will
return advice on modifications that will increase the performance of a sub-optimal
materialized view. For example, this Advisor may suggest splitting the MV into two sub-MVs
or even recommend adding additional MV logs to help the MV to perform more effectively.
In Listing 1.5, Ive created an example Advisor task that asks
DBMS_ADVISOR.TUNE_MVIEW to perform its magic against a few materialized views
that I suspect are candidates for tuning. I've also shown the results of that analysis. Note
that I executed the utlxrw.sql script (found in $ORACLE_HOME/rdbms/admin) to
create table REWRITE_TABLE before executing DBMS_ADVISOR.TUNE_MVIEW.
Trust, But Verify: Materialized View Refresh Using Trusted Constraints

Oracle 10g adds one more powerful feature to MV refreshes: the ability of a materialized
view to choose more query rewrite options, generally resulting in better and more efficient
execution of refreshes, via the USING TRUSTED CONSTRAINTS clause.
For example, if I create a constraint against a column in ENABLE NOVALIDATE mode, that
constraint will only be applied to any new or updated values for that column, and Oracle will
not validate any pre-existing values for that column. If I am willing to take responsibility for
the validity of the pre-existing data, I can specify the keyword RELY for the constraint.
When a materialized view utilizes this data during query rewrite to determine the best
access path for join operations, it assumes that the data in that column is valid.
The USING TRUSTED CONSTRAINTS clause tells Oracle to use dimension and constraint
information that the DBA has declared trustworthy, but that the database has not yet
validated. It is therefore likely that the materialized views refresh performance may
improve as long as the dimension and constraint information is valid. On the other hand, if
Oracle determines that this information is invalid, the refresh procedure may instead corrupt
the materialized view even though the refresh operation itself returns a successful status.
(If USING TRUSTED CONSTRAINTS is not specified, Oracle will use the default method,
USING ENFORCED CONSTRAINTS, during the refresh operation.)
I have constructed three new tables and a new materialized view to represent the start of a
sales force assignment subsystem. (It may appear that Ive gone a long way to demonstrate
a simple concept, but Ill be using these objects extensively in the next article.) Listing 1.6
illustrates how to employ the USING TRUSTED CONSTRAINTS clause in a materialized
view in an attempt to improve its performance. Note that the UNKNOWN_TRUSTED_FD
column of the DBA_MVIEWS data dictionary view will be marked (Y)es when a trusted
constraint has been applied to a materialized view.
Next Steps
As impressive as these materialized view enhancements are, the good news about new
features for materialized views doesnt end here. In my next article, Ill delve into using
Partition Change Tracking (PCT) and Partitioned Maintenance Operations
(PMOPs), two new sets of features that allow a DBA to isolate updates to only those
partitions of a materialized view affected by the refresh operation.
References and Additional Reading
Even though Ive hopefully provided enough technical information in this article to
encourage you to explore with these features, I also strongly suggest that you first review
the corresponding detailed Oracle documentation before proceeding with any experiments.
Actual implementation of these features should commence only after a crystal-clear
understanding exists. Please note that Ive drawn upon the following Oracle 10gR2
documentation for the deeper technical details of this article:
B14200-02 Oracle Database SQL Reference
B14214-01 Oracle Database New Features Guide
B14223-02 Oracle Database Data Warehousing Guide

B14231-01 Oracle Database Administrators Guide


B14237-02 Oracle Database Reference
B14258-01 PL/SQL Packages and Types Reference

Oracle 10g Materialized View


Enhancements, Part 2
By Jim Czuprynski
Synopsis. Oracle 10g Release 2 (10gR2) has improved the effectiveness and speed of
materialized view refreshes, something especially important as data warehouses and data
mart environments become increasingly complex and mission-critical requirements for all
enterprises. This article the last in this series demonstrates how to utilize the new
Partition Change Tracking (PCT) features to speed the refresh of a partitioned
materialized view and how Partition Maintenance Operations (PMOPs) help improve
performance for partitioned materialized views.
In the prior article in this two-part series, I discussed several enhancements for materialized
views in Oracle 10gR2, most notably:

Join-only materialized views (MJVs)


Improved methods for investigating why a materialized view hasn't been rewritten
as expected using EXPLAIN_REWRITE and TUNE_MVIEW procedures of
DBMS_MVIEW

Using trusted constraints to enhance the performance of query rewrite operations

As impressive as those enhancements are, I'll next discuss some equally impressive and
powerful features in this final article in the series. I'll start off with showing how you can use
Partition Change Tracking (PCT) to enable a materialized view to refresh its underlying
data even more quickly by allowing it to refresh only those rows that are affected by
changes in individual partitions of the underlying tables.
Partition Change Tracking
Prior to Oracle 10g, a table's partition key(s) and special partition markers (aka
PMARKERs) had to be identified so that a materialized view could take advantage of
partitioned change tracking for quicker refreshes. Oracle 10g enhances PCT by allowing the
ROWID pseudocolumn to take the place of the partition key or PMARKER columns.
This is especially good news for materialized view joins (MJVs), the new Oracle 10g MV
concept introduced and explained in the previous article in this series. Since in many cases
the ROWID column is already being used within the MVJ's defining query, there is no need
to modify the MVJ's definition to take advantage of this feature. If the underlying partitioned
tables for a materialized view can take advantage of PCT, this metadata is also recorded in

Oracle 10g's data dictionary so when a refresh for the underlying tables is requested, the
refresh can easily take advantage of PCT.
Partition Change Tracking and List Partitioning
PCT works particularly well with list partitioned tables. Listing 2.1 shows the code that I
used to create a new table, SH.LIST_SALES_TIME, that's list-partitioned on its MONTH
column into four quarterly partitions. I then created a new materialized view,
SH.MV_PCT_SALES, that takes advantage of the new partitioned table.
What happens when data is manipulated directly in SH.LIST_SALES_TIME is illustrated in
Listing 2.2. Because I created a materialized view log on that table, PCT fast refresh is
enabled on the SH.MV_PCT_SALES materialized view. When I update data in that
underlying table, Oracle 10g automatically detects this and immediately triggers the refresh
of the materialized view, but it only needs to apply the changes to the data in the affected
quarter's partition. This means that a COMPLETE refresh of that materialized view is
avoided.
Listing 2.3 also includes three queries and the resulting output after I've applied the
updates to the SH.LIST_SALES_TIME table.
Join Dependency and PCT Refreshes
Of course, there are a few restrictions on using PCT. For starters, PCT-based refresh is
available for a materialized view only if it contains a join-dependent expression on columns
in at least one of its detail tables. A join-dependent expression is an expression consisting of
columns from tables directly or indirectly joined through equijoins to the partitioned detail
table on the partitioning key. The set of tables in the path to detail table are termed joindependent tables. Join-dependent tables therefore allow users to create materialized views
containing aggregates on some level higher than the partitioning key of the detail table.
There are some other restrictions as well:

The COMPATIBILITY initialization parameter must be set to at least 9.0.0.0.0.


The materialized view must reference at least one partitioned table.

The underlying partitioned tables must be either list, range, or composite


partitioned.

Only a single column can define the partition key of the top level of the partitioned
table.

Either (a) the partition key column, (b) the partition marker, (c) the ROWID, or (d)
the join dependent expression has to be present in the GROUP BY clause if one is
used to define the materialized view.

Either (a) a ROWID, (b) the detail table's join dependent expression, (c) partition key
column, (d) the partition marker must be included in the materialized view.

Oracle doesn't support PCT for any materialized view that refers to a view, a remote
table, or contains outer joins.

Data can only be changed on the underlying partitioned table. If you want to insure
that PCT refresh will occur for a table that has a join dependent expression in the
materialized view, data modifications can't occur in any of the join dependent tables.

If a materialized view contains a UNION ALL statement, then note that PCT-based
refresh is not possible.

Finally, if either the MODEL clause or an analytic window function is used within the
materialized view, then either (a) the partition key column, (b) the partition marker,
(c), the ROWID, or (d) the join dependent expression has to be listed in each set of
PARTITION BY statements.

Forcing a PCT-Based Refresh with DBMS_MVIEW.REFRESH()


To specifically force the refresh of a PCT-enabled materialized view, Oracle 10g adds a new
value, (P)artitioned, for the METHOD argument of the DBMS_MVIEW.REFRESH()
procedure. Note that if I call this procedure and specify the question mark (?) value for this
argument, Oracle 10g will attempt to figure out if a PCT-based refresh is possible and if so,
it will automatically request the FAST_PCT refresh method rather than a COMPLETE
refresh.
In Listing 2.2, I've demonstrated how to use this feature to refresh the
SH.MV_PCT_SALES PCT refresh enabled materialized view that we've been using in our
current set of examples.
Partition Maintenance Operations (PMOPs)
Since a materialized view is really nothing more than a view with an underlying table,
there's nothing that prohibits that underlying table from being partitioned. Oracle 10g takes
advantage of this by allowing maintenance to be performed against the partitioned data
subsets of a partitioned materialized view whenever that materialized view's source tables
are modified via the ALTER MATERIALIZED VIEW command.
For example, if I drop an entire partition from the underlying table with the ALTER TABLE
<table_name> DROP PARTITION; command, Oracle10g will immediately drop that
corresponding partition from the materialized view during its next refresh. Likewise, if I
issue an ALTER TABLE <table_name> TRUNCATE PARTITION; operation to completely
remove a partition in an underlying partitioned table, then the corresponding data in the
materialized view will be removed completely as well.
There are some restrictions on when PCT will be triggered in concert with a TRUNCATE
PARTITION operation, however:

Both the underlying partitioned table and its materialized view must be rangepartitioned.
A single partition key column must define the partitioned table's partitioning scheme.
The partitions in both the materialized view and its underlying partitioned table must
relate one-to-one.

Because TRUNCATE is a DDL command, the partition will be removed immediately


from the source table, and the data will be removed immediately from the
materialized view; its removal cannot be rolled back.

Listing 2.4 shows how this feature works. I've created a second materialized view,
SH.MV_PCT_PART_SALES, that's partitioned on month number identically to the
SH.LIST_SALES_TIME table. I've then shown what happens when I drop or truncate a
partition of the SH.LIST_SALES_TIME table. Note that the data is immediately refreshed
in both the SH.MV_PCT_PART_SALES and SH.MV_PCT_SALES materialized views to
reflect the change in values in the source table.
Conclusion
The addition of Partition Change Tracking (PCT) features in Oracle 10g significantly expands
the ability to keep materialized views synchronized with the sources of their data, and
Partition Maintenance Operations (PMOPs) offer even faster refreshes of materialized views
when a materialized view is partitioned in the same fashion as its source table.
References and Additional Reading
Even though I've hopefully provided enough technical information in this article to
encourage you to explore with these features, I also strongly suggest that you first review
the corresponding detailed Oracle documentation before proceeding with any experiments.
Actual implementation of these features should commence only after a crystal-clear
understanding exists. Please note that I've drawn upon the following Oracle 10gR2
documentation for the deeper technical details of this article

/*
||
||
||
||
||
||
||
||
||
||
||
||
||
||
||
*/

Oracle 10gR2 Materialized View Enhancements Listing 2


Demonstrates new Oracle 10gR2 Materialized View (MV) features, including:
- Examples of Partition Change Tracking (PCT) for MVs
- How TRUNCATE PARTITION affects an MV that references a partitioned table
- Using Partition Maintenance Operations (PMOPs) with MVs
Author: Jim Czuprynski
Usage Notes:
This script is provided to demonstrate various features of Oracle 10g
materialized view enhancements, and it should be carefully proofread before
executing it against any existing Oracle database to insure that no
potential damage can occur.

/*
|| Listing 2.1: Create a new table for PCT demonstrations. It will contain
||
sales history data copied from SH.SALES, list-partitioned
||
across specific month numbers into four quarters of data
*/
DROP TABLE sh.list_sales_time PURGE;
CREATE table sh.list_sales_time (
time_id
,cust_id
,month
,week
,quantity_sold
,amount_sold
)
PARTITION BY LIST (month)(
PARTITION q1
VALUES ( 1, 2, 3),
PARTITION q2
VALUES ( 4, 5, 6),
PARTITION q3
VALUES ( 7, 8, 9),
PARTITION q4

VALUES (10, 11, 12),


PARTITION others
VALUES (DEFAULT))

AS
SELECT
S.time_id
,S.cust_id
,T.fiscal_month_number
,T.fiscal_week_number
,S.quantity_sold
,S.amount_sold
FROM
sh.sales S
,sh.times T
WHERE S.time_id = T.time_id
AND S.promo_id < 2000
AND T.calendar_year = 2000
;
------ Create a new materialized view based on the new table. Note
-- that a materialized view log is also created to enable PCT
-- features!
----DROP MATERIALIZED VIEW LOG ON sh.list_sales_time;
CREATE MATERIALIZED VIEW LOG
ON sh.list_sales_time WITH ROWID
(month)
INCLUDING NEW VALUES;
DROP MATERIALIZED VIEW sh.mv_pct_sales;
CREATE MATERIALIZED VIEW sh.mv_pct_sales
BUILD IMMEDIATE --DEFERRED
REFRESH FAST ON COMMIT --DEMAND
ENABLE QUERY REWRITE
AS
SELECT
cust_id
,month
,SUM(quantity_sold) as tot_qty_sold
,AVG(quantity_sold) AS avg_qty_sold
,COUNT(quantity_sold) AS cnt_qty_sold
,SUM(amount_sold) as tot_amt_sold
,AVG(amount_sold) AS avg_amt_sold
,COUNT(amount_sold) AS cnt_amt_sold
FROM sh.list_sales_time LS
GROUP BY
cust_id
,month
;
/*
|| Listing 2.2: Demonstrate applying updates to the SH.LIST_SALES_TIME table
||
and their impact on the underlying materialized view
*/
------ Now update just one part of the underlying table ...

----SELECT /*+NOREWRITE*/
MONTH
,SUM(quantity_sold)
,SUM(amount_sold)
FROM sh.list_sales_time
WHERE month IN (1,2,3)
GROUP BY ROLLUP(month);
;
UPDATE sh.list_sales_time
SET
quantity_sold = quantity_sold * 0.80
,amount_sold = amount_sold * 1.20
WHERE month IN (1,2,3);
COMMIT;
SELECT /*+NOREWRITE*/
MONTH
,SUM(quantity_sold)
,SUM(amount_sold)
FROM sh.list_sales_time
WHERE month IN (1,2,3)
GROUP BY ROLLUP(month);
;
------ ... then force the refresh of a PCT-enabled MV with DBMS_MVIEW.REFRESH(),
-- letting Oracle choose the most appropriate refresh method. This should
-- be the (P)artitioned refresh method (FAST_PCT), and Oracle can be forced
-- to use it by specifying (P) for the method in DBMS_MVIEW.REFRESH.
----BEGIN
DBMS_MVIEW.REFRESH(
list => 'sh.mv_pct_sales'
,method => '?'
);
END;
/
/*
|| Listing 2.3: Queries for ascertaining the status of selected
||
materialized views for the SH schema
*/
TTITLE 'Status of SH-Owned Materialized
COL owner
FORMAT A05
COL mview_name
FORMAT A24
COL rewrite_enabled
FORMAT A04
COL refresh_mode
FORMAT A07
COL refresh_method
FORMAT A07
COL fast_refreshable
FORMAT A18
COL refreshed_on
FORMAT A10
COL last_refresh_type
FORMAT A08
COL staleness
FORMAT A07
COL after_fast_refresh FORMAT A07

Views|(From DBA_MVIEWS)'
HEADING 'Owner'
HEADING 'Materialized View'
HEADING 'Qry|Rwr|Enb?'
HEADING 'Refresh|Mode'
HEADING 'Refresh|Method'
HEADING 'Fast|Refresh|-able?'
HEADING 'Last|Refreshed|On' WRAP
HEADING 'Last|Refresh|Type'
HEADING 'Stale?'
HEADING 'After|Fast|Refresh'

SELECT
owner
,mview_name
,rewrite_enabled
,refresh_mode
,refresh_method
,fast_refreshable
,TO_CHAR(last_refresh_date, 'mm-dd-yyyy hh24:mi:ss') refreshed_on
,last_refresh_type
,staleness
,after_fast_refresh
FROM dba_mviews
WHERE owner = 'SH'
ORDER BY last_refresh_date DESC
;
TTITLE OFF
TTITLE 'Analysis of SH-Owned Materialized Views|(From DBA_MVIEW_ANALYSIS)'
COL owner
FORMAT A05
HEADING 'Owner'
COL mview_name
FORMAT A24
HEADING 'Materialized View'
COL refreshed_on
FORMAT A20
HEADING 'Last Refreshed On'
COL refresh_method
FORMAT A07
HEADING 'Refresh|Method'
COL summary
FORMAT A01
HEADING 'S|M|Y|?'
COL unusable
FORMAT A01
HEADING 'U|N|U|?'
COL invalid
FORMAT A01
HEADING 'I|N|V|?'
COL rewrite_enabled
FORMAT A01
HEADING 'R|W|R|?'
SELECT
owner
,mview_name
,TO_CHAR(last_refresh_date, 'mm-dd-yyyy hh24:mi:ss') refreshed_on
,refresh_method
,summary
,unusable
,invalid
,rewrite_enabled
FROM dba_mview_analysis
WHERE owner = 'SH'
ORDER BY last_refresh_date DESC
;
TTITLE OFF
TTITLE 'Last Refreshes of SH-Owned Materialized Views|(From
DBA_MVIEW_REFRESH_TIMES)'
COL owner
FORMAT A05
HEADING 'Owner'
COL name
FORMAT A24
HEADING 'Materialized View'
COL master
FORMAT A24
HEADING 'Master View'
COL refreshed_on
FORMAT A20
HEADING 'Last Refreshed On'
SELECT
owner
,name
,master
,TO_CHAR(last_refresh, 'mm-dd-yyyy hh24:mi:ss') refreshed_on
FROM dba_mview_refresh_times
WHERE owner = 'SH'
ORDER BY last_refresh DESC
;
TTITLE OFF

>>> Results of queries after FAST_PCT refresh operation:


Fri Sep 22
page
1
Status of SH-Owned Materialized Views
(From DBA_MVIEWS)
Last

Qry

Fast

Rwr Refresh Refresh


Refreshed Refresh
Owner Materialized View
Enb? Mode
Method
Type
Stale?
----- ------------------------ ---- ------- ---------------- -------- ------SH
MV_PCT_SALES
Y
COMMIT FAST
2006 FAST_PCT FRESH

Last

Refresh
-able?

On

-----------------DIRLOAD_LIMITEDDML 09-22-

11:54:51
SH
MV_CUST_MTH_SALES
2006 COMPLETE FRESH

DEMAND

FAST

DIRLOAD_DML

09-22-

COMMIT

FAST

DIRLOAD_DML

09-16-

DEMAND

FORCE

DIRLOAD_LIMITEDDML 12-30-

DEMAND

FORCE

DIRLOAD_LIMITEDDML 12-30-

10:31:38
SH
MJV_CURRENT_SALES_FORCE
2006 COMPLETE UNKNOWN
15:37:04
SH
FWEEK_PSCAT_SALES_MV
2005 NA
UNKNOWN
23:32:58
SH
CAL_MONTH_SALES_MV
2005 NA
UNKNOWN
23:32:55
Fri Sep 22
page
1
Analysis of SH-Owned Materialized Views
(From DBA_MVIEW_ANALYSIS)
S
M
Refresh Y
Owner Materialized View
Last Refreshed On
Method ?
----- ------------------------ -------------------- ------- SH
MV_PCT_SALES
09-22-2006 11:54:51 FAST
Y
SH
MV_CUST_MTH_SALES
09-22-2006 10:31:38 FAST
Y
SH
MJV_CURRENT_SALES_FORCE 09-16-2006 15:37:04 FAST
N
SH
FWEEK_PSCAT_SALES_MV
12-30-2005 23:32:58 FORCE
Y

U
N
U
?
N
N
N
N

I
N
V
?
N
N
N
N

R
W
R
?
Y
Y
Y
Y

SH

CAL_MONTH_SALES_MV

12-30-2005 23:32:55

FORCE

Y N N Y

Fri Sep 22
page
1
Last Refreshes of SH-Owned Materialized Views
(From DBA_MVIEW_REFRESH_TIMES)
Owner
----SH
SH
SH
SH
SH
SH
SH
SH
SH
SH
SH
SH
SH

Materialized View
-----------------------MV_PCT_SALES
MV_CUST_MTH_SALES
MV_CUST_MTH_SALES
MV_CUST_MTH_SALES
MJV_CURRENT_SALES_FORCE
MJV_CURRENT_SALES_FORCE
MJV_CURRENT_SALES_FORCE
MJV_CURRENT_SALES_FORCE
FWEEK_PSCAT_SALES_MV
FWEEK_PSCAT_SALES_MV
FWEEK_PSCAT_SALES_MV
CAL_MONTH_SALES_MV
CAL_MONTH_SALES_MV

Master View
-----------------------LIST_SALES_TIME
TIMES
PRODUCTS
SALES
EMPLOYEES
SALES_AREA_HIERARCHIES
SALES_AREAS
SALES_FORCE_ASSIGNMENTS
PRODUCTS
TIMES
SALES
TIMES
SALES

Last Refreshed On
-------------------09-22-2006 11:54:43
09-22-2006 10:31:38
09-22-2006 10:31:38
09-22-2006 10:31:37
09-16-2006 15:37:03
09-16-2006 15:37:03
09-16-2006 15:37:03
09-16-2006 15:37:03
12-30-2005 23:32:58
12-30-2005 23:32:58
12-30-2005 23:32:58
12-30-2005 23:32:53
12-30-2005 23:32:52

/*
|| Listing 2.4: Create a materialized view with an underlying table
||
that is partitioned to demonstrate Partition Maintenance
||
Operations (PMOPs)
*/
------ Create a new materialized view based on table SH.LIST_SALES_TIME.
-- This materialized view (SH.MV_PCT_PART_SALES) is partitioned on
-- the same key as the table, but is a range partition instead of
-- a list partition.
----DROP MATERIALIZED VIEW sh.mv_pct_part_sales;
CREATE MATERIALIZED VIEW sh.mv_pct_part_sales
PARTITION BY RANGE (month)
(
PARTITION per1
VALUES LESS THAN ( 4)
TABLESPACE example
,PARTITION per2
VALUES LESS THAN ( 7)
TABLESPACE example
,PARTITION per3
VALUES LESS THAN (10)
TABLESPACE example
,PARTITION per4
VALUES LESS THAN (13)
TABLESPACE example
)
BUILD IMMEDIATE
REFRESH FAST ON COMMIT

ENABLE QUERY REWRITE


AS
SELECT
cust_id
,month
,SUM(quantity_sold) as tot_qty_sold
,AVG(quantity_sold) AS avg_qty_sold
,COUNT(quantity_sold) AS cnt_qty_sold
,SUM(amount_sold) as tot_amt_sold
,AVG(amount_sold) AS avg_amt_sold
,COUNT(amount_sold) AS cnt_amt_sold
FROM sh.list_sales_time LS
GROUP BY
cust_id
,month
;
------ Example 2.4.1: Results of DROPping a partition
------ Drop the Q1 partition from the SH.LIST_SALES_TIME table ...
ALTER TABLE sh.list_sales_time
DROP PARTITION q1;
-- ... and note that it's immediately reflected in the
-- corresponding materialized views.
COL month
FORMAT 999
HEADING 'Mth'
COL qty_sold
FORMAT 999,999,999 HEADING 'Qty|Sold'
COL amt_sold
FORMAT 999,999,999 HEADING 'Amt|Sold'
TTITLE 'Test 1: After Dropping a Partition|(From SH.LIST_SALES_TIME)'
SELECT
MONTH
,SUM(quantity_sold) qty_sold
,SUM(amount_sold)
amt_sold
FROM sh.list_sales_time
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 1: After Dropping a Partition
(From SH.LIST_SALES_TIME)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
10
21,996
2,268,190
11
21,658
2,172,534
12
16,022
2,291,432
175,357
18,183,860

TTITLE 'Test 1: After Dropping a Partition|(From SH.MV_PCT_SALES)'


SELECT
MONTH
,SUM(tot_qty_sold) qty_sold
,SUM(tot_amt_sold) amt_sold
FROM sh.mv_pct_sales
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 1: After Dropping a Partition
(From SH.MV_PCT_SALES)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
10
21,996
2,268,190
11
21,658
2,172,534
12
16,022
2,291,432
175,357
18,183,860
TTITLE 'Test 1: After Dropping a Partition|(From SH.MV_PCT_PART_SALES)'
SELECT
MONTH
,SUM(tot_qty_sold) qty_sold
,SUM(tot_amt_sold) amt_sold
FROM sh.mv_pct_part_sales
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 1: After Dropping a Partition
(From SH.MV_PCT_PART_SALES)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
10
21,996
2,268,190
11
21,658
2,172,534
12
16,022
2,291,432
175,357
18,183,860
------ Example 2.4.2: Results of TRUNCATing a partition
-----

-- Truncate the Q4 partition from the SH.LIST_SALES_TIME table ...


ALTER TABLE sh.list_sales_time
TRUNCATE PARTITION q4;
-- ... and again, note that it's immediately reflected in the
-- corresponding materialized views.
COL month
FORMAT 999
HEADING 'Mth'
COL qty_sold
FORMAT 999,999,999 HEADING 'Qty|Sold'
COL amt_sold
FORMAT 999,999,999 HEADING 'Amt|Sold'
TTITLE 'Test 2: After Truncating a Partition|(From SH.LIST_SALES_TIME)'
SELECT
MONTH
,SUM(quantity_sold) qty_sold
,SUM(amount_sold)
amt_sold
FROM sh.list_sales_time
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 2: After Truncating a Partition
(From SH.LIST_SALES_TIME)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
115,681
11,451,704
TTITLE 'Test 2: After Truncating a Partition|(From SH.MV_PCT_SALES)'
SELECT
MONTH
,SUM(tot_qty_sold) qty_sold
,SUM(tot_amt_sold) amt_sold
FROM sh.mv_pct_sales
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 2: After Truncating a Partition
(From SH.MV_PCT_SALES)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
115,681
11,451,704
TTITLE 'Test 2: After Truncating a Partition|(From SH.MV_PCT_PART_SALES)'

SELECT
MONTH
,SUM(tot_qty_sold) qty_sold
,SUM(tot_amt_sold) amt_sold
FROM sh.mv_pct_part_sales
GROUP BY ROLLUP(month)
;
TTITLE OFF
Test 2: After Truncating a Partition
(From SH.MV_PCT_PART_SALES)
Qty
Amt
Mth
Sold
Sold
---- ------------ -----------4
22,389
2,168,753
5
16,795
1,522,048
6
18,770
1,687,211
7
20,841
2,291,922
8
17,127
1,693,986
9
19,759
2,087,784
115,681
11,451,704

You might also like