【问题标题】:postgres materialized view refresh performancepostgres物化视图刷新性能
【发布时间】:2020-10-23 14:51:23
【问题描述】:

在 mview mv 中使用了一个表 t,这是 mview 定义中唯一的表。

create table t (c1 int, ..., c10 int);
-- there is a pk on say c1 column
create materialized view mv as select c1, c2...c10 from t;
---there is a unique index on say c5 and bunch of other indexes on the mview.

创建 mview 而不是使用表 t 的原因是,表每隔几个小时就会被截断并重新加载,我们不希望用户在任何时间点看到一个空表,这就是使用 mview 的原因.

使用“同时刷新物化视图”,此 mview 正在被 API 和最终用户使用。

我有几个问题-

  1. 每当同时发生 mview 刷新时,pg 是否会创建另一组表和索引并使用原点进行切换?如果否,是否会更新现有数据?
  2. 如果 mview 的使用量很大,是否会影响刷新过程的性能?反之亦然,如果正在刷新,用户对 mview 的性能是否会受到影响?
  3. mview 有时会在几分钟内刷新,有时则需要数小时。运行时间长了,没有锁,也没有资源短缺,基表的rec数是6m(7.5gb),不算大,为什么刷新mview这么久?
  4. mview 是否需要真空/分析/重新索引?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    问题 1:REFRESH MATERIALIZED VIEW CONCURRENTLY 更新现有物化视图,而不是从头开始构建它。这就是它需要唯一索引的原因,以便可以识别行。

    问题 2:虽然视图可以在刷新时使用,但当然可能会影响性能,因为这两个操作使用相同的资源(CPU、I/O、内存)。

    问题 3:没有更多信息无法回答。物化视图后面的查询是否表现出相同的执行时间变化?

    问题 4:VACUUMANALYZE,是的。 REINDEX 应该不是必需的,除非您测量过度的索引膨胀。

    【讨论】:

    • 谢谢。 Q1 - 它是否执行 upsert 或截断插入?知道它如何应用更改吗? mview 更新是原子的还是可以看到很少更新和很少的旧记录? Q3 - mview 后面的查询是一个简单的选择,它总是立即返回。 mview 的膨胀是否会导致问题?
    • src/backend/commands/matview.c 中阅读refresh_by_match_merge 的评论。这一切都发生在一个事务中,所以它是原子的。
    • 谢谢劳伦兹。 Q3 回复 - 不,它是从单个表中简单选择的。基表被截断并重新加载几乎相同数量的记录。 Mview 是从此基表中的一个简单选择。 mview 有大约 10 个索引,1 个唯一索引和 9 个非唯一索引。使用“insert into select from table”填充基表大约需要 2 分钟,但第一次创建 mview 时需要 16 分钟。即使我删除了除一个唯一索引之外的所有索引,也需要大约 7 分钟。关于为什么它比创建基表(即 2 分钟)花费更长的时间的任何线索。
    • 新填充的表上的第一个选择将设置 提示位。这就是为什么在批量加载后在表上运行 VACUUM 是个好主意的原因之一。
    • 在表被截断并使用插入作为选择填充后,提示位是否也会设置,还是仅在创建表后设置?在我的情况下,截断和插入后在基表上运行真空,mview 创建仍然需要 7 分钟。是否也为 mview 设置了提示位?同样在 pg_class 中,我看到带有一些数字的 toastrelid,我认为这意味着该表有一个 toast 存储。这张表正在通过 toast 进行读取,是否需要一些时间?
    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 2020-12-03
    • 1970-01-01
    • 2016-03-08
    • 2016-05-18
    相关资源
    最近更新 更多