Postgres Inheritance based partition 扫描所有分区
Postgres Inheritance based partition scanning all the partitions
我想在 Postgres 中通过继承实现分区。
我通过参考 Postgres article 实现了以下步骤:-
- 创建了一个名为“test_table”的大师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)
)
- 创建了 child/inherited table
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)
- 已将“BEFORE INSERT”触发器附加到主服务器 table 以将基于列“col3”的数据插入正确的分区 table
DECLARE
v_col3 bigint;
BEGIN
v_col3 := NEW.col3;
EXECUTE 'INSERT INTO kirana_customer.test_table_'||v_col3||' VALUES (.*)' 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 分区的工作方式吗?
您必须将 constraint_exclusion
设置为 on
或 partition
才能生效。
你真的不能用1的样本量得出结论。而且你只有一个child table.
没有限制根table不能包含行where col3=1
,因此需要对其进行扫描。扫描一个空的 able 没什么大不了的,但如果你确实想避免它,你可以添加一个约束:
alter table kirana_customer.test_table add constraint whatever
check (col3 is null) no inherit;
此外,您不想使用声明性分区的理由没有任何意义。也许你应该用一个例子来问一个问题,说明你对此有什么误解。
我想在 Postgres 中通过继承实现分区。 我通过参考 Postgres article 实现了以下步骤:-
- 创建了一个名为“test_table”的大师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)
)
- 创建了 child/inherited table
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)
- 已将“BEFORE INSERT”触发器附加到主服务器 table 以将基于列“col3”的数据插入正确的分区 table
DECLARE
v_col3 bigint;
BEGIN
v_col3 := NEW.col3;
EXECUTE 'INSERT INTO kirana_customer.test_table_'||v_col3||' VALUES (.*)' 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 分区的工作方式吗?
您必须将 constraint_exclusion
设置为 on
或 partition
才能生效。
你真的不能用1的样本量得出结论。而且你只有一个child table.
没有限制根table不能包含行where col3=1
,因此需要对其进行扫描。扫描一个空的 able 没什么大不了的,但如果你确实想避免它,你可以添加一个约束:
alter table kirana_customer.test_table add constraint whatever
check (col3 is null) no inherit;
此外,您不想使用声明性分区的理由没有任何意义。也许你应该用一个例子来问一个问题,说明你对此有什么误解。