简体   繁体   English

物化视图快速刷新-Oracle 12c中的意外行为

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

I've faced unexpected behavior of materialized view fast refresh. 我遇到了物化视图快速刷新的意外行为。 It turns to be that at a background database queries unrelated m.view logs. 事实证明,在后台数据库查询不相关的m.view日志。

Imagine we have two tables with m.view logs and one m.view for one of the tables: 想象一下,我们有两个带有m.view日志的表,一个表的m.view:

  1. table1 - used in m.view and fast refreshable table1-在m.view中使用并且可快速刷新
  2. table2 - no m.view, just m.view log (no m.view for simplification, in our project we have several independent mat.views) table2-没有m.view,只有m.view日志(为简化起见,没有m.view,在我们的项目中,我们有几个独立的mat.views)

Initially fast refresh for table1 works fast. 最初,对table1的快速刷新工作很快。 But if we fill table2 in another session with some big amount of data in one transaction, then fast refresh of m.view for table1 degradates. 但是,如果我们在另一个会话中用一个事务中的大量数据填充table2,则对table1的m.view的快速刷新会降低性能。 Most of the time is spent on select over m.view log for table2, which has no relations to refreshing m.view . 大部分时间都花在选择table2的m.view日志上,这与刷新m.view无关

My database version: 我的数据库版本:

 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. Session 1 - Create tables/m.view logs/m.views: 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. Sesion 1 - check the performance of fast refresh: 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. Session 2 - upload 3 mio of records into table2, don't commit 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. Session 1 - check the performance of fast refresh: 4.会话1-检查快速刷新的性能:

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

PL/SQL procedure successfully completed

Executed in 5,367 seconds

In av$session we see that Session 1 spends most of time for selecting from m.view log for table2: 在av $ session中,我们看到会话1花费大部分时间从m.view日志中选择table2:

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

This is information from the trace file (separate run): 这是来自跟踪文件的信息(单独运行):

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)

Additionally, in the trace file I see that there are queries to ALL the m.view logs in the db, even those that are located in anoter schemas. 此外,在跟踪文件中,我看到对数据库中的所有 m.view日志都有查询,即使是位于注释模式中的查询。

Has anyone else faced such unexpected behavior ? 还有其他人面对过这样的意外行为吗? How did you solve it ? 您是如何解决的? Do you have ideas for workaround ? 您有解决方法的想法吗?


WORKAROUND: 解决方法:

Use timestamp based mat.view logs instead of commit scn based ones. 使用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