首页 文章

Oracle - 如何使用FAST REFRESH和JOINS创建物化视图

提问于
浏览
35

所以我很确定Oracle支持这个,所以我不知道我做错了什么 . 此代码有效:

CREATE MATERIALIZED VIEW MV_Test
  NOLOGGING
  CACHE
  BUILD IMMEDIATE 
  REFRESH FAST ON COMMIT 
  AS
    SELECT V.* FROM TPM_PROJECTVERSION V;

如果我添加一个JOIN,它会中断:

CREATE MATERIALIZED VIEW MV_Test
  NOLOGGING
  CACHE
  BUILD IMMEDIATE 
  REFRESH FAST ON COMMIT 
  AS
    SELECT V.*, P.* FROM TPM_PROJECTVERSION V
    INNER JOIN TPM_PROJECT P ON P.PROJECTID = V.PROJECTID

现在我收到错误:

ORA-12054:无法为实例化视图设置ON COMMIT刷新属性

我在TPM_PROJECT和TPM_PROJECTVERSION上创建了物化视图日志 . TPM_PROJECT的主键为PROJECTID,TPM_PROJECTVERSION的复合主键为(PROJECTID,VERSIONID) . 有什么诀窍呢?我一直在挖掘Oracle手册无济于事 . 谢谢!

4 回答

  • 5

    FAST REFRESH的关键检查包括以下内容:

    1) An Oracle materialized view log must be present for each base table.
    2) The RowIDs of all the base tables must appear in the SELECT list of the MVIEW query definition.
    3) If there are outer joins, unique constraints must be placed on the join columns of the inner table.
    

    No 3很容易错过,值得在这里强调

  • 1

    你有没有ANSI加入尝试过吗?

    CREATE MATERIALIZED VIEW MV_Test
      NOLOGGING
      CACHE
      BUILD IMMEDIATE 
      REFRESH FAST ON COMMIT 
      AS
    SELECT V.*, P.* FROM TPM_PROJECTVERSION V,TPM_PROJECT P 
    WHERE  P.PROJECTID = V.PROJECTID
    
  • 45

    如果您没有为查询引用的主表创建物化视图日志,则会在REFRESH_FAST上收到错误 . 如果有人不熟悉物化视图或第一次使用它,更好的方法是使用oracle sqldeveloper并以图形方式放入选项,并且错误也提供了更好的意义 .

  • 3

    首先,从Oracle Database Data Warehousing Guide开始:

    仅具有联接的物化视图上的快速刷新限制... FROM列表中所有表的行必须出现在查询的SELECT列表中 .

    这意味着您的语句需要看起来像这样:

    CREATE MATERIALIZED VIEW MV_Test
      NOLOGGING
      CACHE
      BUILD IMMEDIATE 
      REFRESH FAST ON COMMIT 
      AS
        SELECT V.*, P.*, V.ROWID as V_ROWID, P.ROWID as P_ROWID 
        FROM TPM_PROJECTVERSION V,
             TPM_PROJECT P 
        WHERE P.PROJECTID = V.PROJECTID
    

    另一个需要注意的关键方面是您的物化视图日志必须创建为 with rowid .

    以下是功能测试场景:

    CREATE TABLE foo(foo NUMBER, CONSTRAINT foo_pk PRIMARY KEY(foo));
    
    CREATE MATERIALIZED VIEW LOG ON foo WITH ROWID;
    
    CREATE TABLE bar(foo NUMBER, bar NUMBER, CONSTRAINT bar_pk PRIMARY KEY(foo, bar));
    
    CREATE MATERIALIZED VIEW LOG ON bar WITH ROWID;
    
    CREATE MATERIALIZED VIEW foo_bar
      NOLOGGING
      CACHE
      BUILD IMMEDIATE
      REFRESH FAST ON COMMIT  AS SELECT foo.foo, 
                                        bar.bar, 
                                        foo.ROWID AS foo_rowid, 
                                        bar.ROWID AS bar_rowid 
                                   FROM foo, bar
                                  WHERE foo.foo = bar.foo;
    

相关问题