2016-09-26 56 views
1

撞上了牆,試圖插入TABLEB與滿足一定的條件後插入到表A物化視圖:彙總查詢涉及partitionn操作

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刷新屬性。 這是一個限制嗎?聚合查詢中沒有分區運算符? 表過大,我想我的觀點僅具有特定於某個特定時期/月 當我刪除PARTITION(PART_201609)跑如下我能夠成功創建視圖的數據:

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

- 編輯 - 包括表A的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'))); 
+0

你可以添加tablea表的DDL - 特別是分區鍵?看起來關鍵不在分組中,這是[PCT]的要求(http://docs.oracle.com/cd/E11882_01/server.112/e25554/advmv.htm#DWHSG00324)。您是否檢查了查詢的[功能](https://docs.oracle.com/cd/E11882_01/server.112/e25554/basicmv.htm#DWHSG8218)? –

+0

在編輯中添加了DDL – Wasky

+1

不熟悉分區表,但是......不是,你不是在MV定義中包含PARTITION規範,而是使用WHERE過濾器嗎? '日期在...和...之間' – mathguy

回答

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, "the materialized view contains partition extended table name"
// *Cause: Fast refresh of materialized aggregate views and/or materialized
// join views are not supported if they were defined using partition
// extended table names.
// *Action: Create the fast refreshable materialized view without using
// partition extended table names or create the materialized view as
// a complete refresh materialized view.

的名字是有點不尋常無妨;你可以通過指定日期範圍來實現同樣的事情,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, "no partition key or PMARKER or join dependent expression in select list"
// *Cause: The capability in question is not supported when the materialized
// view unless the select list (and group by list if a GROUP BY
// clause is present) includes the partition key or
// PMARKER function reference to the table in question or an expression
// join dependent on the partitioning column of the table in question.
// *Action: Add the partition key or a PMARKER function reference or a join dependent
// expression to the select list (and the GROUP BY clause, if present).

...這是關係到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;