1

我有一张桌子

T (A int, B int, C long, D varchar)

由每个分区并由每个A子分区B(即,每个分区都有一个值)。A基数 <10 且B基数 <100。T有大约 60 亿行。

当我运行查询

select distinct B from T where A = 1;

它修剪顶级分区(那些 where A != 1),但对所有子分区执行表扫描以找到B. 我以为它会知道,基于分区设计,它只需要检查分区约束来确定B给定的可能值A,但可惜,事实并非如此。

Aor上没有索引B,但每个分区上都有一个主键(C,D),这似乎无关紧要,但我想我应该提一下。我也有一个 BRIN 索引C。知道为什么 Postgres 查询计划器不咨询子分区约束以避免表扫描吗?

4

1 回答 1

0

原因是没有人在查询计划器中实现这样的优化。我不能说这让我感到惊讶,因为这是一个相当不寻常的查询。优化器中内置的每个此类优化都意味着分区表上的每个查询DISTINCT都需要一些额外的查询计划时间,而只有少数查询会受益。除了编写和维护代码的费用外,这对大多数用户来说都是净损失。

也许您可以使用元数据查询:

CREATE TABLE list (id bigint NOT NULL, p integer NOT NULL) PARTITION BY LIST (p);
CREATE TABLE list_42 PARTITION OF list FOR VALUES IN (42);
CREATE TABLE list_101 PARTITION OF list FOR VALUES IN (101);

SELECT regexp_replace(
          pg_get_expr(
             p.relpartbound,
             p.oid
          ),
          '^FOR VALUES IN \((.*)\)$',
          '\1'
       )::integer
FROM pg_class AS p
   JOIN pg_inherits AS i ON p.oid = i.inhrelid
WHERE i.inhparent = 'list'::regclass;

 regexp_replace 
----------------
             42
            101
(2 rows)
于 2020-10-01T02:18:20.760 回答