分区表的规划时间在 postgres 11 中需要更多时间

Posted

技术标签:

【中文标题】分区表的规划时间在 postgres 11 中需要更多时间【英文标题】:Planning time for partition table is taking more time in postgres 11 【发布时间】:2021-04-14 05:30:13 【问题描述】:

我有少于 200 个分区(每日分区),每个分区有 5M+ 记录。

当我通过直接分区传递一天数据时,我看到估计计划 0.01 毫秒,但使用父表时 190 毫秒(太多)。唯一观察到的区别是附加在计划中。

我们可以在 postgres 11 中消除 Append 或减少 pruning 时间吗?

查询:

explain (ANALYZE, VERBOSE, COSTS, BUFFERS, TIMING,SUMMARY) select 1 from test WHERE date1 >'2021-01-27 13:41:26' and date1<'2021-01-27 21:41:26' and own=123 and mob=123454234

----------------------------plan-----------

Append (cost=0.12..4.19 rows=1 width=4) (actual time=0.018..0.018 rows=0 loops=1) 
  Buffers: shared hit=1 
  -> Index Only Scan using test_20210127_pkey on test_20210127 (cost=0.12..4.17 rows=1 width=4) (actual time=0.017..0.017 rows=0 loops=1) 
     Output: 1 
     Index Cond: ((test_20210127.date1 > '2021-01-27 13:41:26'::timestamp without time zone) AND (test_20210127.date1 < '2021-01-27 21:41:26'::timestamp without time zone) AND (test_20210127.own = 123) AND (test_20210127.mob = 123454234)) 
     Heap Fetches: 0 
     Buffers: shared hit=1 
Planning Time: 190.440 ms 
Execution Time: 0.093 ms

------------截断表结构----

CREATE TABLE public.test
(
    own integer NOT NULL,
    mob bigint NOT NULL,  
    date1 timestamp without time zone NOT NULL,    
    ver integer NOT NULL,
    c5
    ...
    c100
    CONSTRAINT test_pkey PRIMARY KEY (date1, own, mob, ver)
        USING INDEX TABLESPACE tb_1
) PARTITION BY RANGE (date1) 
WITH (
    OIDS = FALSE
)
TABLESPACE tb_1;
 

-- Partitions SQL

CREATE TABLE public.test_20211003 PARTITION OF public.test
    FOR VALUES FROM ('2020-10-03 00:00:00') TO ('2020-10-04 00:00:00');

CREATE TABLE public.test_201004 PARTITION OF public.test
    FOR VALUES FROM ('2020-10-04 00:00:00') TO ('2020-10-05 00:00:00');

  ........6 months partitions

【问题讨论】:

我为你修正了格式。对于未来的问题,请确保您“按原样”粘贴执行计划,而不会弄乱换行符,并确保保留计划的缩进。否则不可读 你为什么使用每天只有 500 万条记录的每日分区?有了这么多的数据,我至少会使用每月的分区。这将只为您提供 200 天的 7 个分区,并且可能会缩短规划时间。 只有我会保留6个月的数据,所以我们可以删除旧分区对吗? 考虑到时间戳的分辨率,在主键中包含时间戳似乎相当奇怪。我知道这是由于 Postgres 没有全局索引造成的,但仍然……如果您删除主键,计划时间会改变吗? 没有PK也同样的问题@a_horse_with_no_name 【参考方案1】:

您可以升级到更高的 PostgreSQL 版本,因为 v12 中有性能改进。

但如果查询执行时间很短,则计划时间总是占主导地位。您可以测试准备好的语句,但我怀疑运行时分区修剪会快得多。

从本质上讲,较差的查询性能是您为以简单的方式丢弃旧数据而付出的预期代价。

【讨论】:

感谢@Laurenz Albe 的回答。但是现在不可能迁移到 12。我也尝试了准备好的语句,但没有用。至少我想减少到小于 40 毫秒。参数设置更改的任何建议。 否;你将不得不忍受它。唯一的补救办法是直接从分区中进行选择 - 但如果您首先必须弄清楚它是哪个分区,那可能至少需要与分区修剪一样长的时间。 为什么追加(计划中)进入一个分区过滤器,如果它超过 1(如果我们过滤超过 1 个日期分区)追加有意义吗?。 那是多余的,但没有害处。如您所见,它需要 0.001 毫秒。

以上是关于分区表的规划时间在 postgres 11 中需要更多时间的主要内容,如果未能解决你的问题,请参考以下文章

Postgres - 内置的自动和动态分区

是否可以在 Postgres 中执行并行查询,使用 union all 查询分区表?

Postgres多分区表的高效查询

索引分区表上的查询计划。避免顺序扫描

PostgreSQL 11中具有自动分区创建功能的表分区?

如何判断 Postgres 表何时聚集以及使用了哪些索引