我在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;
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'
我使用的UPDATE语句是这样的:
UPDATE Programmes_Titles SET Title = 'New title' WHERE rowid = 'AAAL4cAAEAAAftTABB'
此UPDATE语句需要17个小时.
使用INNER JOIN(删除()时)需要几毫秒.
我也尝试在Mv_Web_Programmes物化视图上添加INDEXES,但这似乎也没有帮助. (它仍然运行超过一分钟,这是缓慢的方式,我没有等待每次更改后17小时,所以它可能会改善UPDATE)
所以我的问题是:为什么需要这么长的时间来更新基础表?我怎样才能改善这个?
解决方法
我已经设法在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
不幸的是,正如你所注意到的那样,10g a MV that contains MIN or MAX can only be fast-refreshed on commit after insert(所谓的仅插入MV).上述解决方案不适用于更新/删除(MV必须手动刷新).
您可以跟踪会话并打开跟踪文件以查看执行的SQL查询,以便您可以找到是否可以通过索引对其进行优化.