Oracle-快速刷新具有左连接的物化视图更新速度非常慢

Oracle-快速刷新具有左连接的物化视图更新速度非常慢,oracle,oracle10g,materialized-views,Oracle,Oracle10g,Materialized Views,我在Oracle中有一个物化视图,其中包含一个左连接,需要很长时间才能更新。当我更新基础表时,运行它需要63914.765秒(是的,这几乎是17个小时) 我在同一个表上使用左连接,因为我想将数据从行转到列。pivot命令在此Oracle版本中不可用,并且在快速刷新物化视图上不允许使用GROUP BY+大小写 物化视图日志如下所示: CREATE MATERIALIZED VIEW LOG ON Programmes_Titles WITH PRIMARY KEY, rowid INCLUDING

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

我在同一个表上使用左连接,因为我想将数据从行转到列。pivot命令在此Oracle版本中不可用,并且在快速刷新物化视图上不允许使用GROUP BY+大小写

物化视图日志如下所示:

CREATE MATERIALIZED VIEW LOG ON Programmes_Titles
WITH PRIMARY KEY, rowid
INCLUDING NEW Values;
物化视图本身如下所示(它包含700000行,Programmes\u Titles表包含900000行):

我使用的UPDATE语句如下:

UPDATE Programmes_Titles 
SET Title = 'New title' 
WHERE rowid = 'AAAL4cAAEAAAftTABB'
此更新语句需要17个小时。 使用内部联接(删除(+))时需要毫秒

我还尝试在Mv_Web_程序物化视图上添加索引,但这似乎也没有帮助。(它仍然会运行一分钟以上,这是一种缓慢的方式,我不会在每次更改后等待17个小时,因此它可能会改进更新)


所以我的问题是:为什么更新底层表需要这么长时间?我如何改进这一点?

我已经设法在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开始(即所谓的仅插入MV)。上述解决方案不适用于更新/删除(MV必须手动刷新)


您可以跟踪会话并打开跟踪文件以查看执行了什么SQL查询,这样您就可以找到是否可以通过索引对其进行优化。

我们最近在Oracle 11.2.0.3上也遇到了这个问题

在我们的案例中,由于功能影响,删除“外部连接”是不可避免的

经过调查,发现Oracle使用MV refresh DML添加了一个讨厌的HASH_SH(HASH Semi Join)提示

包括以下博客中提到的内容,一切都不起作用-

最后,一个隐藏的提示起作用了…(虽然一般来说,如果可能的话,应该通过在应用程序中进行更改来避免)

Oracle文档ID 1949537.1建议将hidden _mv_refresh_use_hash_sj参数设置为FALSE,以防止使用该提示

alter session set "_mv_refresh_use_hash_sj"=FALSE;
这使CBO停止使用HASH_SJ提示


为了其他人的利益,将其张贴在此处。

谢谢,建议的解决方案非常有效。还有一个问题。在我的示例查询中,我在联接中只使用一个条件,但我的实际查询使用两个条件。我还可以使用解码功能吗(这对我来说是一个新功能,还是我应该使用一个案例来代替呢?)。节目标题表在不到一秒的时间内用新值更新,但Mv_Web_节目没有更新,旧值仍然存在。有什么想法吗?只要您在案例陈述中使用的每一列都在MV日志中,您应该能够使用案例而不是解码。您是对的,MV在更新/删除后不会更新,请参阅“确定”,谢谢您提供的信息。使用MAX时,似乎不可能获得更新的视图。自/外部联接解决方案也不够快。我无法使用PIVOT,因为10g不支持它。我将尝试考虑另一种解决方案,可能不使用物化视图。既然你回答了我的问题,你就会得到我的投票和回答。
alter session set "_mv_refresh_use_hash_sj"=FALSE;