ORACLE:物化视图的快速刷新在某些情况下不适用于 OUTER JOIN
ORACLE: Fast Refresh on Materialized View not working with OUTER JOIN in some conditions
问题很简单。
我创建了通过外键链接的 TableParent 和 TableChild。
我为两者创建物化视图日志。
我创建了具有快速刷新的物化视图,因为从 TableParent 左连接到 TableChild。
结果是
- 添加子记录,刷新物化视图
- 修改子字段,刷新物化视图
- 添加父记录,实体化视图不刷新
这是代码
-- Tables
CREATE TABLE TABLE_PARENT (
ID NUMBER(10, 0),
TEXT NVARCHAR2(50),
CONSTRAINT PK__TABLE1 PRIMARY KEY (ID)
);
CREATE TABLE TABLE_CHILD (
ID NUMBER(10, 0),
TEXT NVARCHAR2(50),
ID_PARENT NUMBER(10, 0),
CONSTRAINT PK__TABLE2 PRIMARY KEY (ID),
CONSTRAINT FK_TABLE_PARENT FOREIGN KEY (ID_PARENT)
REFERENCES TABLE_PARENT (ID)
);
-- Some record before materialized view creation
INSERT INTO TABLE_PARENT(ID, TEXT) VALUES(1, 'parent1');
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(1, 'child1', 1);
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(2, 'child2', 1);
-- Logs
CREATE MATERIALIZED VIEW LOG on TABLE_PARENT WITH PRIMARY KEY, ROWID;
CREATE MATERIALIZED VIEW LOG on TABLE_CHILD WITH PRIMARY KEY, ROWID;
-- Materialized View
CREATE MATERIALIZED VIEW TABLE_MV
REFRESH FAST ON COMMIT
AS
SELECT TABLE_PARENT.ID ID_PARENT,
TABLE_PARENT.TEXT TEXT_PARENT,
TABLE_CHILD.ID ID_CHILD,
TABLE_CHILD.TEXT TEXT_CHILD,
TABLE_PARENT.ROWID PARENT_ROWID,
TABLE_CHILD.ROWID CHILD_ROWID
FROM TABLE_PARENT,
TABLE_CHILD
WHERE TABLE_PARENT.ID = TABLE_CHILD.ID_PARENT (+);
此时可以验证,第一个结果
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(3, 'child3', 1);
COMMIT;
SELECT * FROM TABLE_MV;
然后是第二个结果
UPDATE TABLE_CHILD SET TEXT = 'child33' WHERE ID = 3;
COMMIT;
SELECT * FROM TABLE_MV;
然后是第三个结果
INSERT INTO TABLE_PARENT(ID, TEXT) VALUES(2, 'parent2');
COMMIT;
SELECT * FROM TABLE_MV;
如您所见,最后一个案例没有刷新Materialized View。我能猜到可能是什么问题,但我想先看看你的解释。我希望我做错了什么,这不是一种 MView 限制问题。我正在研究 Oracle 11g 11.2.0.1.0 版。
非常感谢您的帮助
根据 My Oracle Support - 我发现错误 8856349:快速刷新 OUTER 连接物化视图不起作用
错误已在 11.2.0.1 中确认,已在 11.2.0.2 基本版本中修复。
MOS 说明说解决方法是:
Set the parameter "_mv_refresh_pkfk_relationship_opt"=false.
您可以通过以下方式更改此参数:
alter system set "_mv_refresh_pkfk_relationship_opt"=false scope=both;
但是,由于这是一个隐藏参数,我会咨询 Oracle 支持(如果您有权访问)关于设置此参数的任何潜在副作用,或者彻底测试实例化视图刷新在将其推广到生产系统之前先测试系统。
问题很简单。 我创建了通过外键链接的 TableParent 和 TableChild。 我为两者创建物化视图日志。 我创建了具有快速刷新的物化视图,因为从 TableParent 左连接到 TableChild。
结果是
- 添加子记录,刷新物化视图
- 修改子字段,刷新物化视图
- 添加父记录,实体化视图不刷新
这是代码
-- Tables
CREATE TABLE TABLE_PARENT (
ID NUMBER(10, 0),
TEXT NVARCHAR2(50),
CONSTRAINT PK__TABLE1 PRIMARY KEY (ID)
);
CREATE TABLE TABLE_CHILD (
ID NUMBER(10, 0),
TEXT NVARCHAR2(50),
ID_PARENT NUMBER(10, 0),
CONSTRAINT PK__TABLE2 PRIMARY KEY (ID),
CONSTRAINT FK_TABLE_PARENT FOREIGN KEY (ID_PARENT)
REFERENCES TABLE_PARENT (ID)
);
-- Some record before materialized view creation
INSERT INTO TABLE_PARENT(ID, TEXT) VALUES(1, 'parent1');
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(1, 'child1', 1);
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(2, 'child2', 1);
-- Logs
CREATE MATERIALIZED VIEW LOG on TABLE_PARENT WITH PRIMARY KEY, ROWID;
CREATE MATERIALIZED VIEW LOG on TABLE_CHILD WITH PRIMARY KEY, ROWID;
-- Materialized View
CREATE MATERIALIZED VIEW TABLE_MV
REFRESH FAST ON COMMIT
AS
SELECT TABLE_PARENT.ID ID_PARENT,
TABLE_PARENT.TEXT TEXT_PARENT,
TABLE_CHILD.ID ID_CHILD,
TABLE_CHILD.TEXT TEXT_CHILD,
TABLE_PARENT.ROWID PARENT_ROWID,
TABLE_CHILD.ROWID CHILD_ROWID
FROM TABLE_PARENT,
TABLE_CHILD
WHERE TABLE_PARENT.ID = TABLE_CHILD.ID_PARENT (+);
此时可以验证,第一个结果
INSERT INTO TABLE_CHILD(ID, TEXT, ID_PARENT) VALUES(3, 'child3', 1);
COMMIT;
SELECT * FROM TABLE_MV;
然后是第二个结果
UPDATE TABLE_CHILD SET TEXT = 'child33' WHERE ID = 3;
COMMIT;
SELECT * FROM TABLE_MV;
然后是第三个结果
INSERT INTO TABLE_PARENT(ID, TEXT) VALUES(2, 'parent2');
COMMIT;
SELECT * FROM TABLE_MV;
如您所见,最后一个案例没有刷新Materialized View。我能猜到可能是什么问题,但我想先看看你的解释。我希望我做错了什么,这不是一种 MView 限制问题。我正在研究 Oracle 11g 11.2.0.1.0 版。
非常感谢您的帮助
根据 My Oracle Support - 我发现错误 8856349:快速刷新 OUTER 连接物化视图不起作用
错误已在 11.2.0.1 中确认,已在 11.2.0.2 基本版本中修复。
MOS 说明说解决方法是:
Set the parameter "_mv_refresh_pkfk_relationship_opt"=false.
您可以通过以下方式更改此参数:
alter system set "_mv_refresh_pkfk_relationship_opt"=false scope=both;
但是,由于这是一个隐藏参数,我会咨询 Oracle 支持(如果您有权访问)关于设置此参数的任何潜在副作用,或者彻底测试实例化视图刷新在将其推广到生产系统之前先测试系统。