【发布时间】:2018-02-09 00:54:18
【问题描述】:
我们有一个高度(可能已经结束?)规范化的表,用于跟踪版本化的值。它只是插入,没有更新。
示例数据:
"ID" "Version" "Value"
1 0 "A_1"
2 0 "B_1"
1 1 "A_2"
3 0 "C_1"
我们经常运行查询以仅提取每个 ID 的最新值。当我们达到数百万行时,我们开始遇到性能问题。我已经能够使用物化视图对改进进行原型改进,但无法以它们自刷新“ON COMMIT”的方式创建它们
到目前为止我得到的是这个(以下修订)
CREATE MATERIALIZED VIEW TABLE_LATEST
BUILD IMMEDIATE
REFRESH FAST
ON COMMIT AS
SELECT T.ID
,T.LAST_VERSION
FROM (
SELECT ID
,MAX(VERSION) OVER (PARTITION BY ID) LAST_VERSION
FROM TABLE
) T
GROUP BY T.ID, T.LAST_VERSION;
现在根据反馈进行了修订:
CREATE MATERIALIZED VIEW TABLE_LATEST
BUILD IMMEDIATE
REFRESH FAST
ON COMMIT AS
SELECT ID
,MAX(VERSION)
FROM TABLE
GROUP BY T.ID;
失败的原因是:
ORA-12033: 无法使用实体化视图登录中的筛选列 “模式”。“表”
*Cause: The materialized view log either did not have filter columns logged, or the timestamp associated with the filter columns was more recent than the last refresh time. *Action: A complete refresh is required before the next fast refresh. Add filter columns to the materialized view log, if required.
如果我将Refresh 更改为Force 并删除On Commit,它只会“工作”。我不知道这是否属于物化视图的“无分析”规则,或者我是否一开始就错误地创建了日志?
CREATE MATERIALIZED VIEW LOG ON TABLE
LOGGING
WITH SEQUENCE, ROWID, (VALUE)
INCLUDING NEW VALUES;
表架构:
CREATE TABLE "TABLE"
(
ID NUMBER(10, 0) NOT NULL
, VERSION NUMBER(10, 0) NOT NULL
, VALUE VARCHAR2(4000 CHAR)
, CONSTRAINT MASTERRECORDFIELDVALUES_PK PRIMARY KEY
(
ID
, VERSION
)
USING INDEX
(
CREATE UNIQUE INDEX TABLE_PK ON TABLE(ID ASC, VERSION ASC)
LOGGING
...
)
ENABLE
)
LOGGING
我是否走在正确的轨道上?是否有更好的方法来预先计算最新版本?还是我只需要拨入 Log & View 设置?
【问题讨论】:
-
您是只查询最新版本的单个 id,还是查询多个 id?另外,你的桌子上有什么索引?您还想在物化视图中存储值吗?
-
你经常做哪些操作:
insert/update或select?如果select,您多久需要一次实际版本?如果大多数操作是select的实际值,请尝试创建单独的历史表。您的主表将仅包含实际值(并且不需要在 heave 查询中)和更新触发器以将旧版本复制到历史表。此外,Oracle 拥有Flashback 技术。 -
也许我错了,但
SELECT ID, MAX(LAST_VERSION) AS LAST_VERSION FROM TABLE GROUP BY ID应该足够了。 -
你需要MAX的解析版吗?我似乎记得你不能在 COMMIT 上刷新 MV,除非它是 FAST Refreshable 并且当视图具有分析功能时你不能快速刷新。
-
将
ID和LAST_VERSION列添加到您的实体化视图日志中。将COUNT(*) as ROW_COUNT附加到选择语句。另见docs.oracle.com/cd/B28359_01/server.111/b28313/…
标签: oracle oracle12c materialized-views