日期:2014-05-16  浏览次数:20362 次

query rewrite的理解
我的理解
query rewrite 和 biee中的聚合表功能很像。只不过oracle中用material view来达到目的,在数据库层面实现,发出来的sql一样,从执行计划才能看出来是否走了material view。而biee是在逻辑层进行了自动切换,走相应的聚合表,发出的sql已经表明了要走的聚合表。
?

?

Query Rewrite 在数据仓库是是一个非常有用的技术, Tom在<<Effective Oracle by Design>>一书中将实体化视图(MView)称为是数据仓库的索引, 这是再贴切不过的了, 在OLTP中当SELECT语句的所有的字段都在索引中时, Oracle可以不从表读数据, 而直接从索引中获得全部信息, 而Query Rewrite则是通过创建中间表, 让Oracle自动从创建的中间表读取数据, 而不需要从原表读取了, 这个中间表可以是预先join好的或预先计算好的中间结果. 他的使用就和一般的索引同理了, 虽然你指定的还是那个大表, 但oracle可以为你自动识别可以从那个"数据仓库索引"中读取数据. 下面我们可以来看一下最简单的例子:

SQL> CREATE TABLE DETAIL_TABLE?????????????????????????????????????
? 2? AS SELECT OWNER,OBJECT_NAME FROM sys.dba_objects;?

Table created.

SQL> DESC DETAIL_TABLE
?Name?????????????????????????????? Null???? Type?
?———————————- ——– ————–
?OWNER?????????????????????????????????????? VARCHAR2(30)
?OBJECT_NAME???????????????????????????????? VARCHAR2(128)

SQL> CREATE MATERIALIZED VIEW MID_TABLE ENABLE QUERY REWRITE
? 2? AS
? 3? SELECT OWNER,COUNT(*) TABCNT FROM DETAIL_TABLE GROUP BY OWNER;

Materialized view created.

SQL> DESC MID_TABLE
?Name????????????????????????????? Null???? Type
?——————————— ——– ————–
?OWNER????????????????????????????????????? VARCHAR2(30)
?TABCNT???????????????????????????????????? NUMBER

?

?? 现在假设DETAIL_TABLE是一个非常大的表, MID_TABLE是预先计算好的中间表, 我们来做一个查询测试一下, 要让Oracle使用Query Rewrite,首先要使用CBO,我已经对这个两个表作了分析, 然后将query_rewrite_enabled参数设为True,这个参数可以在session一级更改. 如:

SQL> show parameter query_rewrite_enabled

NAME???????????????????????????????? TYPE??????? VALUE
———————————— ———– ———
query_rewrite_enabled??????????????? string????? FALSE

SQL> SELECT? OWNER,COUNT(*) FROM DETAIL_TABLE
? 2?? WHERE OWNER=’SYSTEM’ GROUP BY OWNER;

OWNER??????????????????????????? COUNT(*)
—————————— ———-
SYSTEM??????????????????????????????? 406

Execution Plan
———————————————————-
?? 0????? SELECT STATEMENT Optimizer=CHOOSE (Cost=4 …)
?? 1??? 0?? SORT (GROUP BY NOSORT) (Cost=4 …)
?? 2??? 1???? TABLE ACCESS (FULL) OF ‘DETAIL_TABLE’ (Cost=4 …

SQL> ALTER SESSION SET query_rewrite_enabled=TRUE;

Session altered.

SQL> SELECT? OWNER,COUNT(*) FROM DETAIL_TABLE
? 2? WHERE OWNER=’S