PostgreSQL 11.0 对分区表的功能进行了增强,其中支持在主表中声明索引,并在子表中自动创建。而在此之前,在主表中声明的索引是无效的,需要分别在子表中去建立索引:
There is no facility available to create the matching indexes on all partitions automatically. Indexes must be added to each partition with separate commands.
— 5.10. Table Partitioning
这一特性的加入可以省去先前的手动建立索引的部分工作。通过这份提交,我们知道在 PostgreSQL 中的分区主表的索引关系类型为 RELKIND_PARTITIONED_INDEX
,与分区主表一样不建立存储,记录在 pg_class 中。新增的 parentIndexId 字段用于维护索引的继承关系,记录在 pg_inherits 中。当子表附加(Attach)至主表时,首先遍历子表索引并与主表索引进行匹配,比较索引信息 CompareIndexInfo 和所属的约束,与主表一致的索引实体会调用 IndexSetParentIndex 和 ConstraintSetParentConstraint 函数将其附加至父索引中,当子表不存在相关索引时才会根据主表声明的索引为子表建立新的索引实体。
分区主表及其声明的索引没有对应的数据文件,在该版本下,它们的表空间属性也会被置为 InvalidOid
。但对于指定表空间的分区索引来说,建立或附加子表时,根据主表索引自动创建的索引实体就无法继承相应的表空间属性。因此在 PostgreSQL 11.1 的版本更新中修复了这一问题:
Ensure that automatically created child indexes are created in the same tablespace as the parent partitioned index.
— E.1. Release 11.1
新增的 ATExecPartedIdxSetTableSpace 函数专门用于设置分区索引的表空间,更新 pg_class 中对应的行而不涉及数据文件的迁移。现在,在分区主表中设置索引的表空间可以应用到各个已附加的分区子表了。不过,在业务系统中如有分区子表指定了不同的表空间,并且又需要分区子表中索引和分区子表存储在同一表空间下的情况,则可能需要实现对分区子表的一些更细粒度的配置和管理逻辑了。