簡體   English   中英

物化視圖快速刷新-Oracle 12c中的意外行為

[英]Materialized view fast refresh - unexpected behavior in Oracle 12c

我遇到了物化視圖快速刷新的意外行為。 事實證明,在后台數據庫查詢不相關的m.view日志。

想象一下,我們有兩個帶有m.view日志的表,一個表的m.view:

  1. table1-在m.view中使用並且可快速刷新
  2. table2-沒有m.view,只有m.view日志(為簡化起見,沒有m.view,在我們的項目中,我們有幾個獨立的mat.views)

最初,對table1的快速刷新工作很快。 但是,如果我們在另一個會話中用一個事務中的大量數據填充table2,則對table1的m.view的快速刷新會降低性能。 大部分時間都花在選擇table2的m.view日志上,這與刷新m.view無關

我的數據庫版本:

 Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production PL/SQL Release 12.1.0.2.0 - Production "CORE 12.1.0.2.0 Production" TNS for Linux: Version 12.1.0.2.0 - Production NLSRTL Version 12.1.0.2.0 - Production 

1.會話1-創建表/m.view日志/m.views:

drop materialized view mv_table1;
drop table table1 purge;
drop table table2 purge;

create table table1(
  a integer primary key,
  b date,
  c varchar2(16)
);

create table table2(
  a integer primary key,
  b date,
  c varchar2(16)
);

create materialized view log on table1
with rowid, sequence, commit scn ( b, c ) including new values;

create materialized view log on table2
with rowid, sequence, commit scn ( b, c ) including new values;

create materialized view mv_table1 (b, c, cnt)
refresh fast on demand
as 
select b, c, count(*) cnt
from   table1 
group by b, c;

2.會話1-檢查快速刷新的性能:

SQL> set timing on
SQL> exec dbms_mview.refresh('MV_TABLE1','F');

PL/SQL procedure successfully completed

Executed in 0,25 seconds

3.會話2-將3個mio記錄上傳到table2中,不要提交

insert into table2(a,b,c)
with get_data(a,b,c,i) as (
  select 1 a,trunc(sysdate) b,to_char(sysdate,'yyyy-mm-dd')||'-'||1 c, 2 i from dual
  union all
  select i, trunc(sysdate)+mod(i,10000),to_char(sysdate+mod(i,10000),'yyyy-mm-dd')||'-'||mod(i,10000), i + 1
  from   get_data
  where  i<= 3000000
)
select a,b,c
from   get_data;

4.會話1-檢查快速刷新的性能:

SQL> set timing on
SQL> exec dbms_mview.refresh('MV_TABLE1','F');

PL/SQL procedure successfully completed

Executed in 5,367 seconds

在av $ session中,我們看到會話1花費大部分時間從m.view日志中選擇table2:

select 1 from "SCOTT"."MLOG$_TABLE2" where rownum=1

這是來自跟蹤文件的信息(單獨運行):

SQL ID: 89s2c53j480vz Plan Hash: 1479141652

select 1
from
 "SCOTT"."MLOG$_TABLE2" where rownum=1


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          4          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      5.88       5.89          0    3058867          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      5.88       5.89          0    3058871          0           0

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS   (recursive depth: 1)
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         0          0          0  COUNT STOPKEY (cr=3058867 pr=0 pw=0 time=5891187 us)
         0          0          0   TABLE ACCESS FULL MLOG$_TABLE2 (cr=3058867 pr=0 pw=0 time=5891181 us cost=7990 size=0 card=1)

此外,在跟蹤文件中,我看到對數據庫中的所有 m.view日志都有查詢,即使是位於注釋模式中的查詢。

還有其他人面對過這樣的意外行為嗎? 您是如何解決的? 您有解決方法的想法嗎?


解決方法:

使用timestamp based mat.view日志,而不是基於commit scn的日志。

解決方法:基於時間戳的mat.view日志快速刷新基於提交scn的mat.view日志的怪異行為看起來像一個Oracle錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM