PostgreSQL 10枚举列LIST分区查询计划异常问题咨询
这不是Bug,是PostgreSQL当前实现的特性(限制)
你遇到的这个情况其实是PostgreSQL处理枚举类型LIST分区时的一个已知行为,并非Bug。下面来拆解背后的原因:
核心逻辑:隐式规则 vs 显式约束
当你基于枚举类型创建LIST分区时:
- PostgreSQL确实会在内部记录每个分区对应的枚举值规则(比如
test_1对应'POSITIVE'),但不会自动将这些规则转化为显式的CHECK约束存储到系统表中。 - 查询优化器的分区裁剪功能,依赖于能从系统表中读取到的显式约束条件来判断哪些分区不需要扫描。没有显式
CHECK约束时,优化器无法确定某个分区只包含特定枚举值,所以只能默认扫描所有分区。
手动添加CHECK约束后的变化
当你手动执行ALTER TABLE ... ADD CONSTRAINT添加针对枚举值的CHECK约束后:
- 这些约束会被写入
pg_constraint系统表,优化器可以直接读取到test_1只包含'POSITIVE'、test_2只包含'NEGATIVE'的明确规则。 - 此时再执行
EXPLAIN,优化器就能准确判断只需要扫描test_2分区,实现了你预期的分区裁剪效果。
为什么PostgreSQL不自动生成这些约束?
这是当前版本PostgreSQL的设计选择:枚举类型的可能值是固定的,但分区机制在处理枚举时,没有将VALUES IN的条件自动映射为显式CHECK约束。不过这并非缺陷,只是优化器在处理这类场景时,需要显式约束的触发才能完成分区裁剪。
你可以通过查询系统表验证这一点:
SELECT conname, conrelid::regclass, consrc FROM pg_constraint WHERE conrelid IN ('test_1'::regclass, 'test_2'::regclass);
创建分区后执行这条语句,不会看到对应的CHECK约束;手动添加约束后,就能看到你创建的约束条目了。
内容的提问来源于stack exchange,提问作者Damir Ciganović-Janković
相关产品推荐
相关产品推荐

