1

问题:当索引处于活动状态时,在完全刷新期间性能显着下降。我不确定为什么在完全刷新期间激活索引会导致性能显着差异。目前,我们的数据仓库存在过度索引的问题,但我很惊讶地看到,即使只有一个活动索引,而完全刷新时没有活动索引,性能也会大幅下降。

甲骨文版本 12c

研究: 物化视图刷新可怕的性能下降 我在 SO 上发现了这一点,但这并不一定能回答我的问题,为什么索引会导致性能下降。我可能会继续建议在完全刷新后删除索引并重建,但我仍在尝试找出原因。

性能测试示例: 我有很多 MV,但这是我如何测试 MV 和相关成本的示例。我已经测试了大约 10 个 MV,它们都显示出相同的模式。请注意,我修改了代码以删除所有对象名称

所有索引都处于活动状态:

exec dbms_mview.refresh('MY_MV_TEST','C');

SQL Developer 报告的实时执行:~153s

获得性能:

SELECT elapsed_time, log_purge_time
FROM dba_mvref_stats
....

elapsed_time = 151 log_purge_time = 1

ALTER INDEX IX_MY_MV_TEST_1 UNUSABLE;
....
ALTER INDEX IX_MY_MV_TEST_13 UNUSABLE;

重新运行完全刷新:

exec dbms_mview.refresh('MY_MV_TEST','C');

从 dba_mvref_stats 获取统计信息:

elapsed_time = 27 log_purge_time = 1

有点惊讶,所以我一个一个地尝试,一次只有 1 个索引处于活动状态。对于每个索引,报告的 elapsed_time 为 33,log_purge_time 为 2(我认为它们都报告了相同的时间有点奇怪)。还有一些其他的 MV 也从 300 秒到 40 秒。到目前为止,我只对我们数据仓库的一小部分进行了测试,我将假设我们的一些较大的 MV 将显示相同的结果。正如 SQL 开发人员报告的那样,索引的重建只需要 11 秒。

MV DDL: 重命名所有对象需要一些时间,但如果需要,我会这样做。目前,这是此特定 MV 定义的总体概述。在 SELECT 子句中只有列、一对 case 语句、一对 substr() 和 cast()。

CREATE MATERIALIZED VIEW MY_MV_TEST 
BUILD DEFERRED 
USING INDEX REFRESH FORCE ON DEMAND 
USING DEFAULT LOCAL ROLLBACK SEGMENT
USING ENFORCED CONSTRAINTS AS
SELECT column1, column2, CASE..., SUBSTR(..), CAST()...
FROM mv1, mv2, mv3
WHERE mv1.column1 = mv2.column1
AND mv1.column1 = mv3.column1
AND ... (other simple conditions using the equality operator)

另请注意,我测试过的所有 MV 都支持 REFRESH FAST。DBMS_MVIEW.EXPLAIN_MVIEW 表明它们具有 REFRESH FAST 能力。我使用 COMPLETE REFRESH 只是为了测试。

4

1 回答 1

1

请检查它是否有助于并行运行刷新:

ALTER SESSION ENABLE PARALLEL DML;

此外,将刷新切换为非原子:

EXEC dbms_mview.refresh(list=>'MY_MV_TEST', method=>'C', atomic_refresh=>false);

然后 Oracle 会自动禁用索引、刷新数据并重建索引,这在大多数情况下会更快。

于 2020-05-01T18:59:04.047 回答