我有 N 个客户端机器。我想用不同的 BRIN 索引分区加载每台机器。
这需要:
- 创建具有预定义分区数量的 BRIN - 等于客户端机器的数量
- 从在 BRIN 分区标识符上使用 WHERE 而不是在索引列上进行过滤的客户端发送查询
主要目标是在将单个表从 postgres 加载到分布式客户端机器时提高性能,保持客户端之间的行数相等 - 或者如果行数不除以机器则接近相等数数。
我目前可以通过维护新列来实现它,该列将我的表分块到与客户端机器数量相等的桶中(或者使用 row_number() over (order by datetime) % N
即时).这样在时间和内存方面效率不高,而 BRIN 索引看起来是一个不错的功能,可以加速此类用例。
3 台客户端机器的最小可重现示例:
CREATE TABLE bigtable (datetime TIMESTAMPTZ, value TEXT);
INSERT INTO bigtable VALUES ('2015-12-01 00:00:00+00'::TIMESTAMPTZ, 'txt1');
INSERT INTO bigtable VALUES ('2015-12-01 05:00:00+00'::TIMESTAMPTZ, 'txt2');
INSERT INTO bigtable VALUES ('2015-12-02 02:00:00+00'::TIMESTAMPTZ, 'txt3');
INSERT INTO bigtable VALUES ('2015-12-02 03:00:00+00'::TIMESTAMPTZ, 'txt4');
INSERT INTO bigtable VALUES ('2015-12-02 05:00:00+00'::TIMESTAMPTZ, 'txt5');
INSERT INTO bigtable VALUES ('2015-12-02 16:00:00+00'::TIMESTAMPTZ, 'txt6');
INSERT INTO bigtable VALUES ('2015-12-02 23:00:00+00'::TIMESTAMPTZ, 'txt7');
预期输出:
- 客户 1
2015-12-01 00:00:00+00, 'txt1'
2015-12-01 05:00:00+00, 'txt2'
2015-12-02 02:00:00+00, 'txt3'
- 客户 2
2015-12-02 03:00:00+00, 'txt4'
2015-12-02 05:00:00+00, 'txt5'
- 客户 3
2015-12-02 16:00:00+00, 'txt6'
2015-12-02 23:00:00+00, 'txt7'
问题:
如何创建具有预定义分区数的 BRIN 并运行对分区标识符进行过滤而不是对索引列进行过滤的查询?
可选地,BRIN(或其他 pg 好东西)可以加速从单个表并行加载多个客户端的任务的任何其他方式?
最佳答案
这听起来像是您想在多台机器上分片一个表,并让每个本地表(全局表的一个分片)都有一个只有一个桶的 BRIN 索引。但这没有任何意义。如果单个 BRIN 索引范围覆盖整个(本地)表,那么它永远不会很有帮助。
听起来您正在寻找的是具有可用于分区排除的 CHECK 约束的分区。 PostgreSQL 长期以来一直支持表继承(尽管不是每个分区都在单独的机器上)。使用此方法,必须为每个分区显式设置 CHECK 约束中涵盖的范围。这种明确指定边界的能力听起来正是您正在寻找的,只是使用了不同的技术。
但是,分区排除约束代码不适用于模数。代码足够聪明,知道 WHERE id=5
只需要检查 CHECK (id BETWEEN 1 and 10)
分区,因为它知道 id=5 意味着id 介于 1 和 10 之间。更准确地说,它知道它的相反数。
但代码从未被编写为知道 WHERE id=5
意味着 id%10 = 5%10
,即使人类知道这一点。因此,如果您在模数运算符上构建分区,例如 CHECK (id%10=5)
而不是在范围上,您将不得不使用 WHERE id = $1 和 id % 散布所有查询10= $1 %10
如果您希望它利用约束。
关于sql - 直接通过 block 范围索引 (BRIN) 标识符查询 Postgres 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34826369/