Partition table 取模,如何索引?数据库
Partition table with modulus, how to Index? PostgreSQL
情况
我在 PostgreSQL 9.5 中有一个数据库用于按时间存储 object 个位置。
我有一个名为 "position" 的主要 table 列(仅相关):
- position_id
- position_timestamp
- object_id
在object_id上被划分为100childtables,条件为:
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
其他 children 依此类推。我使用模数关系进行分区以平均分配 objects。
每个 child 都在 position_id 和 object_id 上建立索引(两个不同的索引)。
问题
当我通过它的 ID 查找 object 时,Postgres 对每个 child table:
运行索引扫描
EXPLAIN ANALYZE
SELECT *
FROM position
WHERE object_id = 3
"Append (cost=0.43..35925.81 rows=51119 width=97) (actual time=0.109..46.362 rows=52418 loops=1)"
" -> Index Scan using position_object_id_position_timestamp_idx on position (cost=0.43..34742.00 rows=24811 width=97) (actual time=0.108..15.367 rows=26209 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_00_object_id_idx on position_object_id_00 (cost=0.29..4.30 rows=1 width=97) (actual time=0.102..0.102 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_01_object_id_idx on position_object_id_01 (cost=0.29..4.30 rows=1 width=97) (actual time=0.065..0.065 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_02_object_id_idx on position_object_id_02 (cost=0.29..4.30 rows=1 width=97) (actual time=0.069..0.069 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Seq Scan on position_object_id_03 (cost=0.00..757.61 rows=26209 width=97) (actual time=0.030..5.337 rows=26209 loops=1)"
" Filter: (object_id = 3)"
" -> Index Scan using position_object_id_04_object_id_idx on position_object_id_04 (cost=0.29..4.30 rows=1 width=97) (actual time=0.067..0.067 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
[...]
除了我的 master table 中有数据(第一行)(参见关于那个的主题 ),Postgres 没有 "recognize" 的检查条件分区并在每个 child table 上查找 ID,而在 table 位置只有相应的 ID_object_id_03.
是否有一种特定的索引方式可以直接知道要查看哪个 table?
Postgres 无法自动将 object_id = 3
的知识应用于检查约束,决定 3 % 100 = 3
并选择相应的分区。提示 postgres 选择哪个分区的唯一方法是在查询中显式使用来自检查约束的表达式,例如:
SELECT * FROM position WHERE object_id = 3 AND object_id % 100 = 3;
顺便说一句,我们正在开发分区的开源扩展 (pg_pathman),它内置了对散列分区的支持,它会自动理解 object_id = 3
对应于某个分区。请检查一下。
情况
我在 PostgreSQL 9.5 中有一个数据库用于按时间存储 object 个位置。
我有一个名为 "position" 的主要 table 列(仅相关):
- position_id
- position_timestamp
- object_id
在object_id上被划分为100childtables,条件为:
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
其他 children 依此类推。我使用模数关系进行分区以平均分配 objects。 每个 child 都在 position_id 和 object_id 上建立索引(两个不同的索引)。
问题
当我通过它的 ID 查找 object 时,Postgres 对每个 child table:
运行索引扫描EXPLAIN ANALYZE
SELECT *
FROM position
WHERE object_id = 3
"Append (cost=0.43..35925.81 rows=51119 width=97) (actual time=0.109..46.362 rows=52418 loops=1)"
" -> Index Scan using position_object_id_position_timestamp_idx on position (cost=0.43..34742.00 rows=24811 width=97) (actual time=0.108..15.367 rows=26209 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_00_object_id_idx on position_object_id_00 (cost=0.29..4.30 rows=1 width=97) (actual time=0.102..0.102 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_01_object_id_idx on position_object_id_01 (cost=0.29..4.30 rows=1 width=97) (actual time=0.065..0.065 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Index Scan using position_object_id_02_object_id_idx on position_object_id_02 (cost=0.29..4.30 rows=1 width=97) (actual time=0.069..0.069 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
" -> Seq Scan on position_object_id_03 (cost=0.00..757.61 rows=26209 width=97) (actual time=0.030..5.337 rows=26209 loops=1)"
" Filter: (object_id = 3)"
" -> Index Scan using position_object_id_04_object_id_idx on position_object_id_04 (cost=0.29..4.30 rows=1 width=97) (actual time=0.067..0.067 rows=0 loops=1)"
" Index Cond: (object_id = 3)"
[...]
除了我的 master table 中有数据(第一行)(参见关于那个的主题
是否有一种特定的索引方式可以直接知道要查看哪个 table?
Postgres 无法自动将 object_id = 3
的知识应用于检查约束,决定 3 % 100 = 3
并选择相应的分区。提示 postgres 选择哪个分区的唯一方法是在查询中显式使用来自检查约束的表达式,例如:
SELECT * FROM position WHERE object_id = 3 AND object_id % 100 = 3;
顺便说一句,我们正在开发分区的开源扩展 (pg_pathman),它内置了对散列分区的支持,它会自动理解 object_id = 3
对应于某个分区。请检查一下。