物化视图:涉及partitionn运算符的聚合查询

时间:2016-09-26 09:41:04

标签: oracle materialized-views

跑到墙上,尝试在插入Tablea后插入具有满足特定条件的行的Tableb

drop materialized view mv ;
drop materialized view log on tablea ;

create materialized view log on tablea
with rowid, sequence ( tino, price )
including new values;

create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT  tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino;

以上将返回ORA-12054:无法设置ON COMMIT Refresh属性。 这是一个限制吗?聚合查询中没有分区运算符? 表太大了,我希望我的视图只有特定时段/月的数据 当我删除PARTITION(PART_201609)并按如下方式运行时,我能够成功创建视图:

create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT  tino,sum(price)
FROM tablea
group by tino;

- 编辑 - 包括tablea的DDL

- 创建表

create table TABLEA
(
tino  NUMBER not null,
price VARCHAR2(200),
dated DATE
)
partition by range (DATED)
(
partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));

1 个答案:

答案 0 :(得分:1)

您可以使用the dbms_mview.explain_mview procedure查看为什么您提出的查询无法用于快速刷新提交MV:

begin
  dbms_mview.explain_mview(q'[SELECT  tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino]');
end;
/

select capability_name, possible, msgno, msgtxt from mv_capabilities_table;

CAPABILITY_NAME                P      MSGNO MSGTXT                                                                                   
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT                            N                                                                                                      
REFRESH_COMPLETE               Y                                                                                                      
REFRESH_FAST                   N                                                                                                      
REWRITE                        Y                                                                                                      
PCT_TABLE                      N       2067 no partition key or PMARKER or join dependent expression in select list                   
REFRESH_FAST_AFTER_INSERT      N       2169 the materialized view contains partition extended table name                              
REFRESH_FAST_AFTER_ONETAB_DML  N       2143 SUM(expr) without COUNT(expr)                                                             
REFRESH_FAST_AFTER_ONETAB_DML  N       2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled                                  
REFRESH_FAST_AFTER_ANY_DML     N       2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled                              
REFRESH_FAST_PCT               N       2157 PCT is not possible on any of the detail tables in the materialized view                  
REWRITE_FULL_TEXT_MATCH        Y                                                                                                      
REWRITE_PARTIAL_TEXT_MATCH     Y                                                                                                      
REWRITE_GENERAL                N       2169 the materialized view contains partition extended table name                              
REWRITE_PCT                    N       2158 general rewrite is not possible or PCT is not possible on any of the detail tables        
PCT_TABLE_REWRITE              N       2185 no partition key or PMARKER in select list                                                

据我所知,没有任何解决2169错误的方法:

  

02169,00000,"物化视图包含分区扩展表名"
  // *原因:快速刷新物化聚合视图和/或具体化   //如果使用分区
来定义连接视图,则不支持它们   //扩展表名。
  // *动作:创建快速可刷新的物化视图,而不使用
  //分区扩展表名或创建物化视图为
  //一个完整的刷新物化视图。

无论如何,按名称指定分区有点不寻常;您可以通过指定日期范围来实现相同的功能,Oracle无论如何都会将查询限制在相关分区。您可以从以下方式获得相同的执行计划:

explain plan for
select tino, sum(price)
from tablea partition(part_201609)
group by tino;

explain plan for
select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino;

--------------------------------------------------------------------------------------------------                                                                                                                                                                                                          
| Id  | Operation               | Name   | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |                                                                                                                                                                                                          
--------------------------------------------------------------------------------------------------                                                                                                                                                                                                          
|   0 | SELECT STATEMENT        |        |     1 |   115 |    15   (7)| 00:00:01 |       |       |                                                                                                                                                                                                          
|   1 |  HASH GROUP BY          |        |     1 |   115 |    15   (7)| 00:00:01 |       |       |                                                                                                                                                                                                          
|   2 |   PARTITION RANGE SINGLE|        |     1 |   115 |    14   (0)| 00:00:01 |     2 |     2 |                                                                                                                                                                                                          
|   3 |    TABLE ACCESS FULL    | TABLEA |     1 |   115 |    14   (0)| 00:00:01 |     2 |     2 |                                                                                                                                                                                                          
--------------------------------------------------------------------------------------------------                                                                                                                                                                                                          

您会看到比我的虚拟表更高的行数,但请注意PSTART和PSTOP列。

使用它作为你的MV仍然不够:

begin
  dbms_mview.explain_mview(q'[select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino]');
end;
/

select capability_name, possible, msgno, msgtxt from mv_capabilities_table;

CAPABILITY_NAME                P      MSGNO MSGTXT                                                                                   
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT                            N                                                                                                      
REFRESH_COMPLETE               Y                                                                                                      
REFRESH_FAST                   N                                                                                                      
REWRITE                        Y                                                                                                      
PCT_TABLE                      N       2067 no partition key or PMARKER or join dependent expression in select list                   
REFRESH_FAST_AFTER_INSERT      N       2081 mv log does not have all necessary columns                                                
REFRESH_FAST_AFTER_ONETAB_DML  N       2143 SUM(expr) without COUNT(expr)                                                             
REFRESH_FAST_AFTER_ONETAB_DML  N       2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled                                  
REFRESH_FAST_AFTER_ONETAB_DML  N       2142 COUNT(*) is not present in the select list                                                
REFRESH_FAST_AFTER_ONETAB_DML  N       2143 SUM(expr) without COUNT(expr)                                                             
REFRESH_FAST_AFTER_ANY_DML     N       2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled                              
REFRESH_FAST_PCT               N       2157 PCT is not possible on any of the detail tables in the materialized view                  
REWRITE_FULL_TEXT_MATCH        Y                                                                                                      
REWRITE_PARTIAL_TEXT_MATCH     Y                                                                                                      
REWRITE_GENERAL                Y                                                                                                      
REWRITE_PCT                    N       2158 general rewrite is not possible or PCT is not possible on any of the detail tables        
PCT_TABLE_REWRITE              N       2185 no partition key or PMARKER in select list                                                

您需要解决2067错误:

  

02067,00000,&#34;选择列表中没有分区键或PMARKER或连接相关表达式&#34;
  // *原因:实现时不支持相关功能   //查看除非选择列表(如果是GROUP BY,则按列表分组)   //子句存在)包括分区键或
  // PMARKER函数引用有问题的表或表达式
  //依赖于相关表格的分区列加入   // *操作:添加分区键或PMARKER函数引用或依赖于连接的
  //表达式到选择列表(以及GROUP BY子句,如果存在)。

...与partition change tracking有关。您可以将a partition marker添加到选择列表和分组,再次获得相同的执行计划(PSTART / PSTOP),但现在允许快速刷新:

explain plan for
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;

select * from table(dbms_xplan.display);

begin
  dbms_mview.explain_mview(q'[select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino]');
end;
/

CAPABILITY_NAME                P      MSGNO MSGTXT                                                                                   
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT                            Y                                                                                                      
REFRESH_COMPLETE               Y                                                                                                      
REFRESH_FAST                   Y                                                                                                      
REWRITE                        Y                                                                                                      
PCT_TABLE                      Y                                                                                                      
REFRESH_FAST_AFTER_INSERT      N       2081 mv log does not have all necessary columns                                                
REFRESH_FAST_AFTER_ONETAB_DML  N       2143 SUM(expr) without COUNT(expr)                                                             
REFRESH_FAST_AFTER_ONETAB_DML  N       2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled                                  
REFRESH_FAST_AFTER_ONETAB_DML  N       2142 COUNT(*) is not present in the select list                                                
REFRESH_FAST_AFTER_ONETAB_DML  N       2143 SUM(expr) without COUNT(expr)                                                             
REFRESH_FAST_AFTER_ANY_DML     N       2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled                              
REFRESH_FAST_PCT               Y                                                                                                      
REWRITE_FULL_TEXT_MATCH        Y                                                                                                      
REWRITE_PARTIAL_TEXT_MATCH     Y                                                                                                      
REWRITE_GENERAL                Y                                                                                                      
REWRITE_PCT                    Y                                                                                                      
PCT_TABLE_REWRITE              Y                                                                                                      

您确实可以使用该查询来创建MV:

create materialized view mv
refresh fast on commit
enable query rewrite
as
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;

Materialized view MV created.

如果要启用MV中的所有功能,可以将dated列添加到MV日志中:

create materialized view log on tablea
with rowid, sequence ( dated, tino, price )
including new values;

并在MV查询中包含缺少的聚合:

select dbms_mview.pmarker(rowid), tino, sum(price), count(price), count(*)
from tablea a
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino

不相关,但请注意,如果它有益,您也可以对MV视图日志进行分区:

create materialized view log on tablea
partition by range (dated)
(
  partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
  partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
  partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
)
with rowid, sequence ( dated, tino, price )
including new values;