Postgres基于继承的分区扫描所有分区



我想在Postgres中通过继承实现分区。我通过参考Postgres文章实现了以下步骤:-

  1. 创建了一个名为test_table的主表
CREATE TABLE kirana_customer.test_table
(
col1 bigint NOT NULL DEFAULT nextval('kirana_customer."testTable_col1_seq"'::regclass),
col2 bigint NOT NULL,
col3 integer,
CONSTRAINT "testTable_pkey" PRIMARY KEY (col1)
)
  1. 创建子表/继承表
CREATE TABLE kirana_customer.test_table_1
(
-- Inherited from table kirana_customer.test_table: col1 bigint NOT NULL DEFAULT nextval('kirana_customer."testTable_col1_seq"'::regclass),
-- Inherited from table kirana_customer.test_table: col2 bigint NOT NULL,
-- Inherited from table kirana_customer.test_table: col3 integer,
CONSTRAINT check_col3 CHECK (col3 = 1)
)
INHERITS (kirana_customer.test_table)
  1. 附加"BEFORE INSERT"触发到主表,用于根据列col3&quot插入数据。到正确的分区表
DECLARE
v_col3 bigint;
BEGIN
v_col3 := NEW.col3;


EXECUTE 'INSERT INTO kirana_customer.test_table_'||v_col3||' VALUES ($1.*)' USING NEW;
RETURN NULL;
END;

在完成所有这些步骤后,我能够将我的条目插入到正确的分区中,但是在分析select语句时,我发现Postgres正在扫描所有分区

explain select * from  kirana_customer.test_table where col3 = 1 

输出如下

"Append  (cost=0.00..34.42 rows=9 width=20)"
"  ->  Seq Scan on test_table  (cost=0.00..3.12 rows=1 width=20)"
"        Filter: (col3 = 1)"
"  ->  Seq Scan on test_table_1  (cost=0.00..31.25 rows=8 width=20)"
"        Filter: (col3 = 1)"

那么,我错过什么了吗?或者这是Postgres分区的工作方式吗?

如果样本量为1,你真的无法得出结论。并且只有一个子表。

不存在根表不能包含行where col3=1的约束,因此需要对其进行扫描。扫描一个空表不是什么大问题,但是如果你确实想避免它,你可以添加一个约束:

alter table kirana_customer.test_table add constraint whatever
check (col3 is null) no inherit; 

同样,您不想使用声明性分区的理由也没有任何意义。也许你应该用一个例子来问一个问题,看看你对此有什么误解。

您必须将constraint_exclusion设置为onpartition才能正常工作。

最新更新