materialized views
来源:互联网 发布:网络运维工具 编辑:程序博客网 时间:2024/05/01 02:48
This article discusses how to plan for MVs, how to set up and confirm different MV capabilities,
how to automatically generate the scripts to create MVs, how to make query rewrite (QR) available,
and how to make sure that QR gets used.
From Queries to Views
The following is a common query at Acme Bank:
SELECT acc_type, SUM(cleared_bal) totbalFROM accountsGROUP BY acc_type;
And the following is an MV, mv_bal , for this query:
CREATE OR REPLACE MATERIALIZED VIEW mv_balREFRESH ON DEMAND ASSELECT acc_type, SUM(cleared_bal) totbalFROM accountsGROUP BY acc_type;
MVs are segments similar to tables, in which the output of queries is
stored in the database.
Now suppose a user wants to get the total of all account balances for the
account type 'C' and issues the following query:
SELECT SUM(cleared_bal)FROM accountsWHERE acc_type = 'C';
Because the mv_bal MV already contains the totals by account type, the user could have
gotten this information directly from the MV, by issuing the following:
SELECT totbalFROM mv_balWHERE acc_type = 'C';
This query against the mv_bal MV would have returned results much more quickly than the
query against theaccounts table. Running a query against the MV will be faster than running
the original query, because querying the MV does not query the source tables.
But there is another difference between querying the source tables and the MV. When a user
executes a query against the source tables, the results return thecurrentdata. Querying the MV,
however, often returns the dataas of the time the MV was created. And because the MV is not
updated when the data in the source tables is, it is bound to get out of sync.
To keep the data in sync, the MV is refreshed from time to time, either manually or automatically.
There are two ways to refresh data in MVs. In one of them, the MV is completely wiped clean and
then repopulated with data from the source tables—a process known ascomplete refresh .
In some cases, however, when the source tables may have changed very little, it is possible
to refresh the MV only for changed records on the source tables—a process known asfast
refresh . To use fast refresh, however, you must have created the MV as fast-refreshable.
Because it updates only changed records, fast refresh is faster than complete refresh.
(See theOracle Database Data Warehousing Guide for more information on refreshing MVs.)
To make sure that users will query MVs at Acme Bank, even if they don't know anything about
the MVs, the bank uses the QR feature. With QR, the database engine can rewrite the original
query from the user to use an MV,automatically , so that the user need not be aware of all the
MVs in place. In some cases, such as in an OLTP system, it may not be desirable to query from
an MV that may not be current with the data in the source tables. QR can be disabled in such
cases—either databasewide, for a specific session, or just for specific MVs.
The DBA can enable QR for a session or for the entire system, by setting the
QUERY_REWRITE_INTEGRITY parameter to true. For any MV to be used in a QR, the MV must have
been built to include theENABLE QUERY REWRITE clause. For example, the following creates
theacc_mgr_view MV with the QR feature from the complex Acme Bank query shown in Listing 1:
CREATE OR REPLACE MATERIALIZED VIEWacc_mgr_viewENABLE QUERY REWRITE AS<the query shown in Listing 1>/
Code Listing 1: Original query
select acc_mgr_id, acc_type_desc, decode (a.sub_acc_type,null,'?', sub_acc_type_desc) sub_acc_type_desc, sum(cleared_bal) tot_cleared_bal, sum(uncleared_bal) tot_uncleared_bal, avg(cleared_bal) avg_cleared_bal, avg(uncleared_bal) avg_uncleared_bal, sum(cleared_bal+uncleared_bal) tot_total_bal, avg(cleared_bal+uncleared_bal) avg_total_bal, min(cleared_bal+uncleared_bal) min_total_balfrom balances b, accounts a, acc_types at, sub_acc_types satwhere a.acc_no = b.acc_noand at.acc_type = a.acc_typeand sat.sub_acc_type (+) = a.sub_acc_typegroup by acc_mgr_id, acc_type_desc, decode (a.sub_acc_type,null,'?', sub_acc_type_desc)
Estimating Space
Converting the query in Listing 1 to an MV is easy, but there are several questions to answer
before creating the MV, including how much space it will occupy and how many rows it will contain.
The DBMS_MVIEW package in Oracle Database 10g will help get these answers. To estimate
the size of the proposed MV, the script in Listing 2 callsDBMS_MVIEW.ESTIMATE_MVIEW_SIZE.
Code Listing 2: Estimating MV size
set serveroutput on size 999999declare l_num_rows number; l_num_bytes number; l_stmt varchar2(2000);begin l_stmt := 'select acc_mgr_id, <the query shown in Listing 1> (a.sub_acc_type,null,''?'', sub_acc_type_desc)'; dbms_mview.estimate_mview_size ( stmt_id => 'Est1', select_clause => l_stmt, num_rows => l_num_rows, num_bytes => l_num_bytes ); dbms_output.put_line('Number of rows = '||l_num_rows); dbms_output.put_line('Size (bytes) = '||l_num_bytes);end;/Number of rows = 2829000Size (bytes) = 667644000
The output in Listing 2 estimates that the MV will contain 2,829,000 rows and that it's going
to be about 667MB in size. These are approximations made from optimizer statistics gathered
on the source tables earlier, and the exact values may be different. But it helps plan for space
and determine in which tablespace to place this MV.
Checking Capabilities
The DBMS_MVIEW.EXPLAIN_MVIEW procedure checks the features and capabilities of an MV
before it is created and writes the results to a table namedMV_CAPABILITIES_TABLE. First,
the DBA creates this table, by running the utlxmv.sql script in the rdbms/admin directory under
Oracle Home.
Listing 3 uses the DBMS_MVIEW.EXPLAIN_MVIEW procedure to see what type of operations
the proposed MV can be used for.
After the first part of Listing 3 populates the results in MV_CAPABILITIES_TABLE, the second
part (after the -- Now check the capabilities comment) goes on to select from that table,
as shown in the SELECT ROWNUM, CAPABILITY_NAME, ...query. To aid in the explanation
of the output, the query uses ROWNUMto denote line numbers.
Code Listing 3: Checking capabilities
declare l_stmt varchar2(2000);begin l_stmt := 'select acc_mgr_id, <the query shown in Listing 1> (a.sub_acc_type,null,''?'', sub_acc_type_desc)'; dbms_mview.explain_mview ( stmt_id => 'MV_Tune1', mv => l_stmt );end;/---- Now check the capabilities--SELECT ROWNUM, CAPABILITY_NAME, POSSIBLE, MSGTXT, RELATED_TEXTFROM mv_capabilities_tableWHERE STATEMENT_ID = 'Est1'AND CAPABILITY_NAME LIKE 'REFRESH%'ORDER BY SEQ/-- Output-- LN CAPABILITY_NAME P MSGTXT RELATED_TEXT --- -------------------------------------- -- --------------------------------- ------------------- 1 REFRESH_COMPLETE Y 2 REFRESH_FAST N 3 REFRESH_FAST_AFTER_INSERT N agg(expr) requires AVG_CLEARED_BAL correspondingCOUNT(expr) function 4 REFRESH_FAST_AFTER_INSERT N one or more joins present in mv 5 REFRESH_FAST_AFTER_INSERT N GROUP BY clause in mv 6 REFRESH_FAST_AFTER_INSERT N aggregate function in mv 7 REFRESH_FAST_AFTER_INSERT N the detail table does not ARUP.SUB_ACC_TYPES not have a materialized view log 8 REFRESH_FAST_AFTER_ONETAB_DML N SUM(expr) without TOT_TOTAL_BAL COUNT(expr) 9 REFRESH_FAST_AFTER_ONETAB_DML N SUM(expr) without TOT_UNCLEARED_BAL COUNT(expr) 10 REFRESH_FAST_AFTER_ONETAB_DML N SUM(expr) without TOT_CLEARED_BAL COUNT(expr) 11 REFRESH_FAST_AFTER_ONETAB_DML N see the reason why REFRESH_FAST_AFTER_INSERT is disabled 12 REFRESH_FAST_AFTER_ANY_DML N see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled 13 REFRESH_FAST_PCT N PCT is not possible on any of the detail tables in the materialized view
The results in Listing 3 tell the story. The CAPABILITY_NAMEcolumn lists the different
refresh capabilities, and the column POSSIBLE (P) shows via a simple Y (yes) orN (no)
whether that capability is possible in this MV. The MV is capable of being completely
refreshed, as shown in line 1, but it's not capable of being fast-refreshed, as shown in line 2.
Why not? The DBA goes down the list to see why the refresh-related features are not possible.
Line 3 indicates that the fast refresh is not possible because the MV does not have aCOUNT()
expression in the query where aggregation functions such asSUM()are used. If an MV uses
aggregation functions, then COUNT() must be in the query to make it fast-refreshable. The
columnRELATED_TEXT in the output shows which columns in the MV are being referred to
in theMSGTXT column. The result agg(expr)—short for aggregation(expression)—inMSGTXT
in line 3 refers to the column AVG_CLEARED_BALin the MV. Because theAVG(CLEARED_BAL)
clause is used in the query to build the MV, there must additionally be aCOUNT(CLEARED_BAL)
or COUNT(*) expression to make the MV fast-refreshable.
Additionally, fast refreshes require the creation of materialized view logs on the base table.
These logs record the changes occurring in the base tables. During fast refresh, these logs
are read by the refresh process to determine the changes to apply to the MV. In line 7,
the MSGTXT column shows the detail table does not have a materialized view
logand the RELATED_TEXT column shows the table on which MV logs are not
present—ARUP.SUB_ACC_TYPES.
Generating Scripts
After the Acme DBA uses the information in Listing 3 to make the planned MV capable of fast
refresh, it's time to generate the file that will generate the MV. The procedure in Listing 4 specifies
a task name and passes it and the SQL query (in Listing 1) to theDBMS_ADVISOR.TUNE_MVIEW
procedure to generate all necessary SQL statements to create the MV. After the DBA runs the
script in Listing 4, running the following script generates the recommendations of the DBMS Advisor:
CREATE DIRECTORY TMP_DIR AS '/tmp'/BEGIN DBMS_ADVISOR.CREATE_FILE ( DBMS_ADVISOR.GET_TASK_SCRIPT ('MV_Tune_Task1'), 'TMP_DIR', 'mv_tune_task1.sql');END;
Code Listing 4: Generating scripts
declare l_stmt varchar2(2000); l_task_name varchar2(30);begin l_task_name := 'MV_Tune_Task1'; l_stmt := 'create materialized view acc_mgr_view enable query rewrite as ... <the query shown in Listing 1>...'; dbms_advisor.tune_mview ( task_name => l_task_name, mv_create_stmt => l_stmt );end;/
This creates a file named mv_tune_task1.sql in the /tmp directory that contains all the SQL
statements needed to create the MV logs on all the necessary base tables and create the
MV with all the appropriate parameters to make it fast-refreshable. Running the
mv_tune_task1.sql file in SQL*Plus will create all the necessary objects. The mv_tune_task1.sql
file is available asListing 8.
Confirming Query Rewrite
Listing 5 contains another popular user query at Acme Bank; it uses column, table, and
function information similar to that of the query in theacc_mgr_viewMV. Listing 5 also uses
the AUTOTRACEfeature of SQL*Plus to provide information on whether QR occurs when the
query runs. TheAUTOTRACE output clearly shows that the query uses all the source tables,
not the materialized view,acc_mgr_view . Why?
Code Listing 5: Confirming query rewrite
SQL> alter session set query_rewrite_enabled = true;Session altered.SQL> set autotrace traceonly explainSQL> select acc_type_desc, sum(cleared_bal) 2 from balances b, accounts a, acc_types at 3 where a.acc_no = b.acc_no 4 and at.acc_type = a.acc_type 5 group by acc_type_desc;Execution Plan-------------------------------------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=533 Card=4 Bytes=112) 1 0 SORT (GROUP BY) (Cost=533 Card=4 Bytes=112) 2 1 HASH JOIN (Cost=523 Card=50000 Bytes=1400000) 3 2 HASH JOIN (Cost=146 Card=50000 Bytes=850000) 4 3 TABLE ACCESS (FULL) OF 'ACC_TYPES' (TABLE) (Cost=3 Card=4 Bytes=40) 5 3 TABLE ACCESS (FULL) OF 'ACCOUNTS' (TABLE) (Cost=140 Card=100000 Bytes=700000) 6 2 TABLE ACCESS (FULL) OF 'BALANCES' (TABLE) (Cost=106 Card=100000 Bytes=1100000)
Running the utlxrw.sql script in $ORACLE_HOME/rdbms/admin sets up a table named
REWRITE_TABLE , whose results will help determine why the optimizer did not use QR on
the query in Listing 5. Running theDBMS_VIEW.EXPLAIN_REWRITEprocedure, shown in
Listing 6, populates theREWRITE_TABLE table with the findings. Querying theMESSAGE
column in REWRITE_TABLE provides the reason why:
SQL> SELECT MESSAGE FROMREWRITE_TABLE;QSM-01110: a lossy join in MV, ACC_MGR_VIEW, between tables, ACCOUNTS and SUB_ACC_TYPES, not found in query
Code Listing 6: Checking for query rewrite
truncate table rewrite_table/declare l_stmt varchar2(2000); l_task_name varchar2(30);begin l_stmt := 'select acc_type_desc, sub_acc_type, sum(cleared_bal) from balances b, accounts a, acc_types atwhere a.acc_no = b.acc_noand at.acc_type = a.acc_typegroup by acc_type_desc, sub_acc_type'; dbms_mview.explain_rewrite ( query => l_stmt, mv => 'ACC_MGR_VIEW', statement_id => 'MV_Explain_RW1' );end;/commit/select message from rewrite_table/
The result shows that QR will not occur because the joins used in the MV and in the
query are different. In the MV, four tables—ACCOUNTS, BALANCES, ACC_TYPES, and
ACC_SUB_TYPES —are joined. However, the new query joins only three tables, leaving
SUB_ACC_TYPES, which is reported in the MESSAGEcolumn. The absence of this join
would have meant inaccurate results if QR were used, so the optimizer decided not to use it.
Rewriting the query in Listing 5 to include another predicate, AND
SAT.ACC_SUB_TYPE = A.ACC_SUB_TYPE , and place the table ACC_SUB_TYPE SAT in
the FROM clause should make QR possible. This revised query is in Listing 7. After the
DBA passes the revised query to the procedure in Listing 6, examining theREWRITE_TABLE
provides the good news:
SQL> SELECT MESSAGE FROM REWRITE_TABLE;QSM-01033: query rewritten with materialized view, ACC_MGR_VIEW
Code Listing 7: Rewrite of Listing 5, confirming query rewrite
SQL> set autotrace traceonly explainSQL> select acc_type_desc, 2 sum(cleared_bal) 3 from balances b, 4 accounts a, 5 acc_types at, 6 sub_acc_types sat, 7 where a.acc_no = b.acc_no 8 and at.acc_type = a.acc_type 9 and sat.sub_acc_type = a.sub_acc_type 10 group by acc_type_descSQL> /Execution Plan-------------------------------------------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=4 Bytes=64) 1 0 SORT (GROUP BY) (Cost=6 Card=4 Bytes=64) 2 1 MAT_VIEW REWRITE ACCESS (FULL) OF 'ACC_MGR_VIEW' (MAT_VIEW REWRITE) (Cost=5 Card=1600 Bytes=25600)
Running the revised query in Listing 7 confirms that the optimizer rewrites the query
and generates the execution plan, also included in Listing 7. This plan shows that the
ACC_MGR_VIEW MV is used instead of the base tables, even though the user specified
them in the query. QR is indeed happening.
Code Listing 8: Generated script for creating MV and MV logs
Rem SQL Access Advisor: Version 10.1.0.1 - ProductionRem Rem Username: ARUPRem Task: MV_Tune_Task1Rem Execution date: Rem set feedback 1set linesize 80set trimspool onset tab offset pagesize 60whenever sqlerror CONTINUECREATE MATERIALIZED VIEW LOG ON "ARUP"."ACCOUNTS" WITH ROWID, SEQUENCE("ACC_NO","ACC_TYPE","SUB_ACC_TYPE","ACC_MGR_ID") INCLUDING NEW VALUES;ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."ACCOUNTS" ADD ROWID, SEQUENCE("ACC_NO","ACC_TYPE","SUB_ACC_TYPE","ACC_MGR_ID") INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW LOG ON "ARUP"."BALANCES" WITH ROWID, SEQUENCE("ACC_NO","CLEARED_BAL","UNCLEARED_BAL") INCLUDING NEW VALUES;ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."BALANCES" ADD ROWID, SEQUENCE("ACC_NO","CLEARED_BAL","UNCLEARED_BAL") INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW LOG ON "ARUP"."ACC_TYPES" WITH ROWID, SEQUENCE("ACC_TYPE","ACC_TYPE_DESC") INCLUDING NEW VALUES;ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."ACC_TYPES" ADD ROWID, SEQUENCE("ACC_TYPE","ACC_TYPE_DESC") INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW LOG ON "ARUP"."SUB_ACC_TYPES" WITH ROWID, SEQUENCE("SUB_ACC_TYPE","SUB_ACC_TYPE_DESC") INCLUDING NEW VALUES;ALTER MATERIALIZED VIEW LOG FORCE ON "ARUP"."SUB_ACC_TYPES" ADD ROWID, SEQUENCE("SUB_ACC_TYPE","SUB_ACC_TYPE_DESC") INCLUDING NEW VALUES;CREATE MATERIALIZED VIEW ARUP.ACC_MGR_VIEW REFRESH FAST WITH ROWID ENABLE QUERY REWRITE AS SELECT ARUP.SUB_ACC_TYPES.SUB_ACC_TYPE_DESC C1, ARUP.ACC_TYPES.ACC_TYPE_DESC C2, ARUP.ACCOUNTS.ACC_MGR_ID C3, ARUP.ACCOUNTS.SUB_ACC_TYPE C4, SUM("ARUP"."BALANCES"."CLEARED_BAL") M1, COUNT("ARUP"."BALANCES"."CLEARED_BAL") M2, SUM("ARUP"."BALANCES"."UNCLEARED_BAL") M3, COUNT("ARUP"."BALANCES"."UNCLEARED_BAL") M4, SUM(("ARUP"."BALANCES"."UNCLEARED_BAL" + "ARUP"."BALANCES"."CLEARED_BAL")) M5, COUNT(("ARUP"."BALANCES"."UNCLEARED_BAL" + "ARUP"."BALANCES"."CLEARED_BAL")) M6, COUNT(*) M7 FROM ARUP.SUB_ACC_TYPES, ARUP.ACC_TYPES, ARUP.BALANCES, ARUP.ACCOUNTS WHERE ARUP.ACCOUNTS.SUB_ACC_TYPE = ARUP.SUB_ACC_TYPES.SUB_ACC_TYPE AND ARUP.ACCOUNTS.ACC_TYPE = ARUP.ACC_TYPES.ACC_TYPE AND ARUP.ACCOUNTS.ACC_NO = ARUP.BALANCES.ACC_NO GROUP BY ARUP.SUB_ACC_TYPES.SUB_ACC_TYPE_DESC, ARUP.ACC_TYPES.ACC_TYPE_DESC, ARUP.ACCOUNTS.ACC_MGR_ID, ARUP.ACCOUNTS.SUB_ACC_TYPE;whenever sqlerror EXIT SQL.SQLCODEbegin dbms_advisor.mark_recommendation('MV_Tune_Task1',1,'IMPLEMENTED');end;/
Preventing Runaway Queries
As demonstrated in Listing 5, if the user writes the query a little differently, the optimizer
does not rewrite the query to select from the MV and the query selects from the base
tables directly. The user may think that the query is rewritten and that the results are
coming from the MV, but in fact, the query is not rewritten and the results are coming
from the source tables, extending the response time significantly.
The REWRITE_OR_ERROR hint in the SQL query will make sure the query is rewritten to
select from the MV or at least inform the user if that does not happen. The following adds
theREWRITE_OR_ERROR hint to the SQL query in which QR did not occur (Listing 5):
SELECT /*+ REWRITE_OR_ERROR */ SELECT acc_type_desc, sub_acc_type_desc,...
The query returns the following error message if it does not rewrite:
ORA-30393: a query block in the statement did not rewrite
Conclusion
Oracle provides tools for creating, managing, and tuning MVs in theDBMS_MVIEWpackage.
Acme Bank is seeing increased query performance, using QR whenever possible and
using error messages from queries that do not rewrite to further optimize its use of MVs and QR.
- materialized views
- Materialized Views
- oracle use materialized views
- PostgreSQL/Materialized Views
- Refreshing Materialized Views
- Brief introduction into Materialized Views
- PostgreSQL::Snapshots aka Materialized Views
- Materialized Views 物化视图 -基础篇
- Requirements for Materialized Views with Aggregates
- Oracle Materialized Views Containing Joins Only
- DW: Some useful system views when checking Materialized View
- Materialized Views in Oracle--Oracle的物化视图
- ORA-10652: Object has on-commit materialized views
- Overview of Materialized Views【每日一译】--20121203
- materialized view Define Constraints on Views【每日一译】--20121204
- ORACLE9i_性能调优基础十三(Materialized Views)
- materialized view
- materialized view
- C语言不定参数
- 数据结构&算法实践—【排序|交换排序】梳子排序
- 控件(四)——TreeView控件以SiteMapdataSource控件为数据源实现最简单的站点地图
- flex&bison 学习笔记
- 矩阵求导计算法则
- materialized views
- Android生存指南:解Bug策略和思路
- kde下sudo出现cannot connect to xserver解决方法
- 唐僧师徒诠释当今社会--搞笑
- cvcopy实现不规则图片提取
- TMS320F28335及其最小系统设计
- 【转载】ADS1.2连接器使用手册 有|Image$$RO$$Limit|等说明
- 预处理 const 与 sizeof
- 从百度一下看用户体验设计的重要性