Oracle - FAST REFRESH使用LEFT JOINS更新的物化视图非常慢

Tej*_*ejo 5 oracle materialized-views oracle10g

我在Oracle中有一个包含LEFT JOIN的物化视图,需要很长时间才能更新.当我更新基础表时,运行需要63914.765秒(是的,这几乎是17个小时).

我在同一个表上使用LEFT JOIN,因为我想将数据从行转移到列.此Oracle版本中不提供pivot命令,并且在FAST REFRESH物化视图上不允许使用GROUP BY + CASE.

物化视图日志如下所示:

CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
WITH PRIMARY KEY, rowid
INCLUDING NEW Values;
Run Code Online (Sandbox Code Playgroud)

Materialized View本身看起来像这样(它包含700000行,Programmes_Titles表包含900000行):

CREATE MATERIALIZED VIEW Mv_Web_Programmes
REFRESH FAST ON COMMIT 
AS

SELECT
    t1.ProgrammeId,        
    t1.Title as MainTitle,
    t2.Title as SecondaryTitle,
    --Primary key
    t1.Title_Id as t1_titleId,
    t2.Title_Id as t2_titleId,

    t1.rowid as t1_rowid,
    t2.rowid as t2_rowid
FROM
    Programmes_Titles t1, 
    Programmes_Titles t2
WHERE
    t1.Titles_Group_Type = 'mainTitle'
    AND t1.Programme_Id = t2.Programme_Id(+) AND t2.Titles_Group_Type(+) = 'secondaryTitle'
Run Code Online (Sandbox Code Playgroud)

我使用的UPDATE语句是这样的:

UPDATE Programmes_Titles 
SET Title = 'New title' 
WHERE rowid = 'AAAL4cAAEAAAftTABB'
Run Code Online (Sandbox Code Playgroud)

此UPDATE语句需要17个小时.使用INNER JOIN(删除(+))时,需要几毫秒.

我也尝试在Mv_Web_Programmes物化视图上添加INDEXES,但这似乎也没有帮助.(它仍然运行超过一分钟,这是缓慢的方式,我没有等待每次更改后17小时,所以它可能会改善UPDATE)

所以我的问题是:为什么需要这么长的时间来更新基础表?我怎样才能改善这个?

Vin*_*rat 3

我已成功在 10.2.0.3 实例上重现您的问题。自连接和外连接似乎是主要问题(尽管 MV 的每一列都有索引,它最终在一分钟内完成了更新)。

起初我以为你可以使用聚合 MV:

SQL> CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
  2  WITH PRIMARY KEY, ROWID (programmeId, Titles_Group_Type, title)
  3  INCLUDING NEW Values;

Materialized view log created

SQL> CREATE MATERIALIZED VIEW Mv_Web_Programmes
  2  REFRESH FAST ON COMMIT
  3  AS
  4  SELECT ProgrammeId,
  5         MAX(decode(t1.Titles_Group_Type, 'mainTitle', t1.Title)) MainTl,
  6         MAX(decode(t1.Titles_Group_Type, 'secondaryTitle', t1.Title)) SecTl
  7    FROM Programmes_Titles t1
  8   GROUP BY ProgrammeId;

Materialized view created
Run Code Online (Sandbox Code Playgroud)

不幸的是,正如您所注意到的,从 10g 开始,包含 MIN 或 MAX 的 MV 只能在插入后提交时快速刷新(所谓的仅插入 MV)。上述解决方案不适用于更新/删除(必须手动刷新 MV)。

您可以跟踪您的会话并打开跟踪文件以查看执行了哪些 SQL 查询,以便您可以发现是否可以通过索引对其进行优化。