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

jan*_*cki 13 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');
Run Code Online (Sandbox Code Playgroud)

预期产量:

  • 客户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'
Run Code Online (Sandbox Code Playgroud)
  • 客户2

2015-12-02 03:00:00+00, 'txt4'
2015-12-02 05:00:00+00, 'txt5'
Run Code Online (Sandbox Code Playgroud)
  • 客户3

2015-12-02 16:00:00+00, 'txt6'
2015-12-02 23:00:00+00, 'txt7'
Run Code Online (Sandbox Code Playgroud)

问题:
如何使用预定义数量的分区创建BRIN并运行过滤分区标识符而不是过滤索引列的查询?
可选地,BRIN(或其他pg好东西)可以加速从单个表并行加载多个客户端的任务吗?

Gre*_*mec -1

基本上,您需要知道的是加载后关系的大小,然后pages_per_range应将存储参数设置为为您提供所需分区数量的除数。

不需要引入人为的分区ID,因为有足够的类型和运算符的支持。物理表布局在这里重要,因此,如果您坚持将分区 ID 作为关键,并最终在自然加载顺序和人工分区 ID 之间引入无序映射,请确保将表聚集在该列的创建 BRIN 之前的排序顺序。

然而,同时请记住,离散值越多,命中索引的机会就越大,因此基数越高越好 - 人工分区标识符的基数是自然键的 1/n,其中 n 是每个分区有不同的值。

更多内容请参见此处此处