问题描述
我正在尝试使用 ENABLE ON QUERY computation 创建以下物化视图,但我找不到问题所在。
我有三个主表,其中包含相应的物化视图日志和所需的列。有人可以帮我吗?
谢谢
create materialized view log on alfaods.OdsReceivable with rowid,sequence ( dueDate,recvChargeTypeId,scheduleId,amount ),primary key including new values for fast refresh;
create materialized view log on alfaods.OdsChargeType with rowid,sequence ( code ),primary key including new values for fast refresh;
create materialized view log on alfaods.OdsScheduleMain with rowid,primary key including new values for fast refresh;
那么MV是
create materialized view alfaods.mv_max_fn_date
TABLESPACE TBDATA
CACHE
LOGGING
NOCOMPRESS
noparaLLEL
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
ENABLE QUERY REWRITE
ENABLE ON QUERY computation
AS
SELECT max(receivable.dueDate) as finalDate,schedule.id as scheduleId,receivable.recvChargeTypeId as recvChargeTypeId,receivable.scheduleId as receivableSchId,receivable.amount as recamount,chargeType.code as ChargTypecode
FROM ALFAODS.OdsReceivable receivable
INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id
INNER JOIN ALFAODS.OdsScheduleMain schedule on receivable.scheduleId = schedule.id
where
receivable.amount NOT IN (0.01,0.00)
AND chargeType.code = 2
group by schedule.id,receivable.recvChargeTypeId,receivable.scheduleId,receivable.amount,chargeType.code
;
当我尝试创建它时,出现此错误
sql> create materialized view alfaods.mv_max_fn_date
TABLESPACE TBDATA
CACHE
LOGGING
NOCOMPRESS
noparaLLEL
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
ENABLE QUERY REWRITE
ENABLE ON QUERY computation
AS
SELECT max(receivable.dueDate) as finalDate,chargeType.code as ChargTypecode
FROM ALFAODS.OdsReceivable receivable
INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id
INNER JOIN ALFAODS.OdsScheduleMain schedule on receivable.scheduleId = schedule.id
where
receivable.amount NOT IN (0.01,0.00)
AND chargeType.code = 2
group by schedule.id,chargeType.code
25 ;
AND chargeType.code = 2
*
ERROR at line 23:
ORA-32361: cannot ENABLE ON QUERY computation for the materialized view
Elapsed: 00:00:00.00
sql>
好像where条件有问题,所以我测试了一下,没有where
sql> create materialized view alfaods.mv_max_fn_date
TABLESPACE TBDATA
CACHE
LOGGING
NOCOMPRESS
noparaLLEL
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
ENABLE QUERY REWRITE
ENABLE ON QUERY computation
AS
SELECT max(receivable.dueDate) as finalDate,chargeType.code as ChargTypecode
FROM ALFAODS.OdsReceivable receivable
INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id
INNER JOIN ALFAODS.OdsScheduleMain schedule on receivable.scheduleId = schedule.id
--where
--receivable.amount NOT IN (0.01,0.00)
--AND chargeType.code = 2
group by schedule.id,chargeType.code
;
INNER JOIN ALFAODS.OdsScheduleMain schedule on receivable.scheduleId = schedule.id
*
ERROR at line 20:
ORA-32361: cannot ENABLE ON QUERY computation for the materialized view
更新
我运行了 DBMS_MVIEW.EXPLAIN_MVIEW
set serveroutput on size unlimited echo on long 99999999 longchunksize 99999999
declare
a sys.ExplainMVArrayType;
begin
dbms_mview.explain_mview('SELECT receivable.recvChargeTypeId as recvChargeTypeId,receivable.scheduleId as scheduleId,chargeType.id as ChargeID,max(receivable.dueDate) as finalDate
FROM ALFAODS.OdsReceivable receivable
INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id
group by receivable.recvChargeTypeId,chargeType.id',a);
dbms_output.put_line('Explain MV '
|| a(1).mvowner || '.' || a(1).mvname);
for i in 1..a.count loop
dbms_output.put_line(
rpad(a(i).capability_name,30)
|| ' [' || case a(i).possible
when 'T' then 'TRUE'
when 'F' then 'FALSE'
else a(i).possible
end || ']'
|| case when a(i).related_num != 0 then
' ' || a(i).related_text
|| ' (' || a(i).related_num || ')'
end
|| case when a(i).msgno != 0 then
' ' || a(i).msgtxt
|| ' (' || a(i).msgno || ')'
end
);
end loop;
end;
/
Explain MV .
PCT [FALSE]
REFRESH_COMPLETE [TRUE]
REFRESH_FAST [FALSE]
REWRITE [TRUE]
REFRESH_FAST_AFTER_INSERT [FALSE] join may produce duplicate rows in mv
(2059)
REFRESH_FAST_AFTER_INSERT [FALSE] MV is not fast refreshable even with view
merging (2154)
REFRESH_FAST_AFTER_ONETAB_DML [FALSE] FINALDATE (193) mv uses the MIN or MAX
aggregate functions (2086)
REFRESH_FAST_AFTER_ONETAB_DML [FALSE] see the reason why
REFRESH_FAST_AFTER_INSERT is disabled (2146)
REFRESH_FAST_AFTER_ONETAB_DML [FALSE] mv uses the MIN or MAX aggregate
functions (2086)
REFRESH_FAST_AFTER_ANY_DML [FALSE] see the reason why
REFRESH_FAST_AFTER_ONETAB_DML is disabled (2161)
REFRESH_FAST_PCT [FALSE] PCT FAST REFRESH is not possible if query
contains an inline view (2196)
REWRITE_FULL_TEXT_MATCH [TRUE]
REWRITE_PARTIAL_TEXT_MATCH [TRUE]
REWRITE_GENERAL [FALSE] the reason why the capability is disabled
has escaped analysis (2141)
REWRITE_PCT [FALSE] general rewrite is not possible or PCT is
not possible on any of the detail tables (2158)
解决方法
我终于可以制作这样的MV了。我不得不从 MV 中删除 MAX 函数,而我会在查询中使用它,这是我想避免的。无论如何,这里是脚本
SQL> @rebmv.sql
SQL> drop materialized view log on alfaods.OdsScheduleMain ;
Materialized view log dropped.
Elapsed: 00:00:00.05
SQL> drop materialized view log on alfaods.OdsChargeType ;
Materialized view log dropped.
Elapsed: 00:00:00.03
SQL> drop materialized view log on alfaods.OdsReceivable ;
Materialized view log dropped.
Elapsed: 00:00:00.04
SQL> drop materialized view alfaods.mv_max_fn_date ;
Materialized view dropped.
Elapsed: 00:00:00.14
SQL>
SQL> create materialized view log on alfaods.OdsScheduleMain with rowid,sequence ( maturityDate,alfascheduleidentifier,scheduleStatus,terminationDate,totalAssetCostFinanced,capitalOutstanding,activationDate,agreementId,invCusId,dealerid,invCompanyId,agrCompanyId ),primary key including new values for fast refresh;
Materialized view log created.
Elapsed: 00:00:00.06
SQL>
SQL> create materialized view log on alfaods.OdsChargeType with rowid,sequence ( code ),primary key including new values for fast refresh;
Materialized view log created.
Elapsed: 00:00:00.03
SQL>
SQL> create materialized view log on alfaods.OdsReceivable with rowid,sequence ( dueDate,recvChargeTypeId,scheduleId,amount ),primary key including new values for fast refresh;
Materialized view log created.
Elapsed: 00:00:00.02
SQL>
SQL> create materialized view alfaods.mv_max_fn_date
2 TABLESPACE TBDATA
3 CACHE
4 LOGGING
5 NOCOMPRESS
6 NOPARALLEL
7 BUILD IMMEDIATE
8 REFRESH FAST ON DEMAND
9 ENABLE QUERY REWRITE
10 ENABLE ON QUERY COMPUTATION
11 AS
12 SELECT count(*) as contador,13 receivable.dueDate as finalDate,14 schedule.id as scheduleId,15 receivable.recvChargeTypeId as recvChargeTypeId,16 receivable.scheduleId as recScheduleId
17 FROM ALFAODS.OdsReceivable receivable
18 INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id
19 INNER JOIN ALFAODS.OdsScheduleMain schedule on receivable.scheduleId = schedule.id
20 where
21 receivable.amount NOT IN (0.01,0.00)
22 AND chargeType.code = 2
23 group by receivable.dueDate,schedule.id,receivable.recvChargeTypeId,receivable.scheduleId
24 ;
Materialized view created.
Elapsed: 00:00:21.94
SQL>
SQL> create index alfaods.idx_mv_max_fn_date on alfaods.mv_max_fn_date ( scheduleId ) nologging nocompress tablespace tbdata ;
Index created.
Elapsed: 00:00:04.13
SQL>
SQL> exec dbms_stats.gather_table_stats('ALFAODS','MV_MAX_FN_DATE',method_opt=> 'FOR ALL COLUMNS SIZE AUTO',cascade => true);
PL/SQL procedure successfully completed.
Elapsed: 00:00:08.36
SQL>
SQL> exec dbms_mview.refresh ('ALFAODS.MV_MAX_FN_DATE','F');
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.46
SQL>