Can';在Oracle中创建包含部分主键的物化视图时,请不要设置“提交时刷新”属性

Can';在Oracle中创建包含部分主键的物化视图时,请不要设置“提交时刷新”属性,oracle,primary-key,materialized-views,Oracle,Primary Key,Materialized Views,我需要将作为主键一部分的列的唯一值从表中提取到物化视图中。如果使用“refresh complete”(刷新完成),我可以创建物化视图,但如果尝试使用“提交时快速刷新”,则没有运气。谁能指出我是否遗漏了什么,或者Oracle不支持这样的行动 下面列出了示例输出。谢谢 SQL> create table TEST( col1 number, col2 number, col3 varchar(32), CONSTRAINT test_pk Primary Key (col1, col2));

我需要将作为主键一部分的列的唯一值从表中提取到物化视图中。如果使用“refresh complete”(刷新完成),我可以创建物化视图,但如果尝试使用“提交时快速刷新”,则没有运气。谁能指出我是否遗漏了什么,或者Oracle不支持这样的行动

下面列出了示例输出。谢谢

SQL> create table TEST( col1 number, col2 number, col3 varchar(32), CONSTRAINT test_pk Primary Key (col1, col2));

Table created.

SQL> create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test;
create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test
                                                                                                     *
ERROR at line 1:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view


SQL> create materialized view test_mv build immediate refresh complete as select distinct col2 from test;

Materialized view created.

SQL> drop materialized view test_mv;

Materialized view dropped.

SQL> create materialized view log on test;

Materialized view log created.

SQL> create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test;
create materialized view test_mv build immediate refresh fast on commit as select distinct col2 from test
                                                                                                     *
ERROR at line 1:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view

你观点的主要问题是DISTINCT子句。提交时快速刷新对底层查询非常敏感。要使物化视图支持快速刷新,必须满足许多规则。明显地阻止它

您可以使用
DBMS\u MVIEW检查物化视图的功能。EXPLAIN\u MVIEW
过程:

DECLARE
    result SYS.EXPLAINMVARRAYTYPE := SYS.EXPLAINMVARRAYTYPE();
BEGIN
    DBMS_MVIEW.EXPLAIN_MVIEW('TEST_MV', result);

    FOR i IN result.FIRST..result.LAST LOOP
        DBMS_OUTPUT.PUT_LINE(result(i).CAPABILITY_NAME || ': ' || CASE WHEN result(i).POSSIBLE = 'T' THEN 'Yes' ELSE 'No' || CASE WHEN result(i).RELATED_TEXT IS NOT NULL THEN ' because of ' || result(i).RELATED_TEXT END || '; ' || result(i).MSGTXT END);
    END LOOP;
END;

您可以在文档中找到更多信息,快速刷新视图很挑剔。此解决方案需要具有特定属性的物化视图日志,以及具有一些额外功能和不同语法的物化视图

DISTINCT
本身似乎不受支持。但也有一些支持
groupby
。如果使用
启用查询重写
创建物化视图,Oracle可以在
不同的
查询中使用它。还有一个额外的
COUNT(*)
,因为“COUNT(*)必须始终存在以保证所有类型的快速刷新。”

创建表、物化视图日志和物化视图。

create table test(col1 number, col2 number, col3 varchar(32)
  ,constraint test_pk primary key (col1, col2));
create materialized view log on test with rowid (col2) including new values;
create materialized view test_mv
  build immediate
  refresh fast on commit
  enable query rewrite as
  select col2, count(*) total from test group by col2;
查询可以使用物化视图。

create table test(col1 number, col2 number, col3 varchar(32)
  ,constraint test_pk primary key (col1, col2));
create materialized view log on test with rowid (col2) including new values;
create materialized view test_mv
  build immediate
  refresh fast on commit
  enable query rewrite as
  select col2, count(*) total from test group by col2;
这些解释计划表明,物化视图适用于
分组依据
不同的
查询

explain plan for select col2 from test group by col2;
select * from table(dbms_xplan.display);

explain plan for select distinct col2 from test;
select * from table(dbms_xplan.display);


Plan hash value: 1627509066

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     1 |    13 |     2   (0)| 00:00:01 |
|   1 |  MAT_VIEW REWRITE ACCESS FULL| TEST_MV |     1 |    13 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

你说得对,这是显而易见的。但是,奇怪的是,您可以创建一个带有
groupby
的查询,Oracle可以将其用于
不同的
查询。有关详细信息,请参阅我的答案。由于我使用的是Oracle SE,我没有查询重写支持,但我仍然可以创建物化视图,而无需“enable query rewrite”子句。缺点是,当运行答案中的两个查询时,它将导致完全表访问。不管怎样,我现在不担心这个问题,我相信一旦我转到Oracle EE,这个问题就会消失。我现在感到困惑的是,在基本表测试中更新col2之后,mv没有得到更新/刷新。在基表中插入新记录后,mv将得到更新。还有什么我遗漏/误解的吗?这是我遗漏的-聚合物化视图应该包含一个
COUNT(*)
。修改后的示例效果更好。请像符咒一样工作!mv已成功更新。伟大的