sql - 直接通过 block 范围索引 (BRIN) 标识符查询 Postgres 表

标签 sql postgresql postgresql-9.5

我有 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/

相关文章:

postgresql - 如何启动 psql 命令行?

Postgresql - 索引删除的行

shell - -su : syntax error near unexpected token '('

mysql - 如何修复: SQL search in multiple joined tables no result

mysql - SQL INSERT INTO 多个表

sql - 如何在 postgres 查询中按正则表达式分组

PostgreSQL 复制具有两列重复的行

postgresql - 如何检查触发器函数中是否存在列?

sql - 是否有任何纯 sql 方法可以通过以下方式从日志表中删除数据

mysql - 在 MySQL (BigQuery) 中查找所有平均结果的最大值