Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 使用物化视图跟踪记录的最新版本_Oracle_Oracle12c_Materialized Views - Fatal编程技术网

Oracle 使用物化视图跟踪记录的最新版本

Oracle 使用物化视图跟踪记录的最新版本,oracle,oracle12c,materialized-views,Oracle,Oracle12c,Materialized Views,我们有一个高度(可能超过?)规范化的表,用于跟踪版本化的值。它只是插入,没有更新 示例数据: "ID" "Version" "Value" 1 0 "A_1" 2 0 "B_1" 1 1 "A_2" 3 0 "C_1" 我们经常运行查询,只提取每个ID的最新值。当我们访问数百万行时,我们开始遇到性能问题。我已经能够使用物化视图对改进进行原型化,但无法以“提交

我们有一个高度(可能超过?)规范化的表,用于跟踪版本化的值。它只是插入,没有更新

示例数据:

"ID"    "Version"   "Value"
1       0           "A_1"
2       0           "B_1"
1       1           "A_2"
3       0           "C_1"
我们经常运行查询,只提取每个ID的最新值。当我们访问数百万行时,我们开始遇到性能问题。我已经能够使用物化视图对改进进行原型化,但无法以“提交时”自我刷新的方式创建它们

到目前为止,我得到的是这个(修订如下)

由于反馈,现在对其进行了修订:

CREATE MATERIALIZED VIEW TABLE_LATEST 
    BUILD IMMEDIATE
    REFRESH FAST 
    ON COMMIT AS

SELECT  ID
       ,MAX(VERSION)
FROM    TABLE
GROUP BY T.ID;
它失败于:

ORA-12033:无法使用物化视图登录中的筛选器列 架构“.”表

只有当我将
Refresh
更改为
Force
并在提交时删除
时,它才会“工作”。我不知道这是否属于物化视图的“无分析”规则,或者我是否一开始就错误地创建了日志

CREATE MATERIALIZED VIEW LOG ON TABLE
LOGGING 
WITH SEQUENCE, ROWID, (VALUE) 
INCLUDING NEW VALUES;
表架构:

CREATE TABLE "TABLE"
(
  ID NUMBER(10, 0) NOT NULL 
, VERSION NUMBER(10, 0) NOT NULL 
, VALUE VARCHAR2(4000 CHAR) 
, CONSTRAINT MASTERRECORDFIELDVALUES_PK PRIMARY KEY 
  (
    ID
  , VERSION 
  )
  USING INDEX 
  (
      CREATE UNIQUE INDEX TABLE_PK ON TABLE(ID ASC, VERSION ASC) 
      LOGGING 
      ...
  )
  ENABLE 
) 
LOGGING 

我走对了吗?是否有更好的方法来预计算最新版本?或者我只需要拨入日志和视图设置吗?

很抱歉,我不能马上给你答复。一个原因可能是使用了MVs不太支持的分析函数。要分析问题,您需要查看物化视图的功能

DECLARE
  -- Local variables here
  --
  v_sql VARCHAR2(32000) := 'SELECT  T.ID
                                   ,T.LAST_VERSION
                            FROM (SELECT  ID
                                         ,MAX(VERSION) OVER (PARTITION BY ID) LAST_VERSION    
                                  FROM    TABLE) T
                                  GROUP BY T.ID
                                          ,T.LAST_VERSION';

   v_msg_arrray SYS.EXPLAINMVARRAYTYPE;
   msg SYS.ExplainMVMessage;
BEGIN
  -- Test statements here
   dbms_mview.explain_mview(mv => v_sql, msg_array => v_msg_arrray);



  FOR i IN v_msg_arrray.FIRST..v_msg_arrray.LAST LOOP
    msg := v_msg_arrray(i);
    DBMS_OUTPUT.put_line('MVOWNER:' || msg.MVOWNER);
    DBMS_OUTPUT.put_line('MVNAME:' || msg.MVNAME);
    DBMS_OUTPUT.put_line('CAPABILITY_NAME:' || msg.CAPABILITY_NAME);
    DBMS_OUTPUT.put_line('POSSIBLE:' || msg.POSSIBLE);
    DBMS_OUTPUT.put_line('RELATED_TEXT:' || msg.RELATED_TEXT);
    DBMS_OUTPUT.put_line('RELATED_NUM:' || msg.RELATED_NUM);
    DBMS_OUTPUT.put_line('MSGNO:' || msg.MSGNO);    
    DBMS_OUTPUT.put_line('MSGTXT:' || msg.MSGTXT);
    DBMS_OUTPUT.put_line('SEQ:' || msg.SEQ);
    DBMS_OUTPUT.put_line('----------------------------------------');
  END LOOP;

END;
顺便说一句:您可以编写更简单的查询:

SELECT t.id,
       MAX(t.version) AS last_version
FROM table t
GROUP BY t.id;

如果您不需要与最新版本关联的值,则只需执行以下操作:

CREATE MATERIALIZED VIEW LOG ON t1 
LOGGING  
WITH SEQUENCE, ROWID, (val) 
INCLUDING NEW VALUES;

create materialized view t1_latest
refresh fast on commit
as
  select id,
         max(version) latest_version
  from   t1
  group by id;
可以找到这方面的测试用例


否则,您需要创建三个独立的MVs(因为您不能有一个快速刷新的提交物化视图,该视图涉及保持稠密的排名第一/最后)-如所示:

主表上的物化视图日志:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;
第一个物化视图:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;
第一个物化视图上的物化视图日志:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;
第二个物化视图:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;
第一个物化视图上的物化视图日志:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;
第三个也是最后一个物化视图:

CREATE MATERIALIZED VIEW LOG ON t1
LOGGING 
WITH SEQUENCE, ROWID, (val)
INCLUDING NEW VALUES;
create materialized view t1_sub_mv1
refresh fast on commit
as
  select id,
         max(version) latest_version,
         count(version) cnt_version,
         count(*) cnt_all
  from   t1
  group by id;
create materialized view log on t1_sub_mv1
with rowid, sequence (id, latest_version, cnt_version, cnt_all)
including new values;
create materialized view t1_sub_mv2
refresh fast on commit
as
  select id,
         version,
         max(val) max_val_per_id_version,
         count(*) cnt_all
  from   t1
  group by id,
           version;
create materialized view log on t1_sub_mv2
with rowid, sequence (id, max_val_per_id_version, cnt_all)
including new values;
create materialized view t1_main_mv
refresh fast on commit
as
  select mv1.id,
         mv1.latest_version,
         mv2.max_val_per_id_version val_of_latest_version,
         mv1.rowid mv1_rowid,
         mv2.rowid mv2_rowid
  from   t1_sub_mv1 mv1,
         t1_sub_mv2 mv2
  where  mv1.id = mv2.id
  and    mv1.latest_version = mv2.version;

可以找到对此的支持测试用例。

您是只查询最新版本的单个id,还是查询多个id?另外,表上有哪些索引?您还想在物化视图中存储值吗?您更经常执行哪些操作:
插入
/
更新
选择
?如果
选择
,您需要实际版本的频率是多少?如果大多数操作都是
选择实际值的
,请尝试创建单独的历史表。您的主表将只包含实际值(并且不需要在垂荡查询中)和更新触发器以将旧版本复制到历史表。Oracle也有这项技术。也许我错了,但是
SELECT ID,MAX(最新版本)由于表GROUP BY ID的最后一个\u版本应该足够了。您是否需要MAX的分析版本。我似乎记得,您不能在提交时进行MV刷新,除非它是快速刷新的,并且当视图具有分析功能时,您不能快速刷新。将列
ID
最后一个\u版本
添加到物化视图中日志追加
COUNT(*)作为行数
以选择语句。另请参见您的第一个建议,我已经更新了我的代码以匹配您的示例(包括简化的基本查询),但它不允许我另存为
快速刷新
(请参见文章中的更新代码和错误)。如果没有这一点,提交插入将以分钟的顺序进行;我想我已经解决了。我在基表中有额外的列,这些列显然也需要添加到日志中,即使它们没有在MV中使用。我还使用MV分层技术为结果添加了额外的数据,谢谢!