【发布时间】:2016-04-21 22:48:10
【问题描述】:
我有 N 台客户端机器。我想用 BRIN 索引的不同分区加载每台机器。
这需要:
- 使用预定义的分区数创建 BRIN - 等于客户端计算机的数量
- 从在 BRIN 分区标识符上使用 WHERE 而非在索引列上过滤的客户端发送查询
主要目标是在将单个表从 postgres 加载到分布式客户端机器时提高性能,保持客户端之间的行数相等 - 或者如果 rows count 不除以 machines 则接近相等数。
我目前可以通过维护新列来实现它,该列将我的表分成等于客户端机器数量的桶(或即时使用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 好东西)可以加快从单个表并行加载多个客户端的任务的任何其他方式?
【问题讨论】:
-
这可能在dba.stackexchange.com上更成功
-
多个客户端意味着多个会话。我认为您不能(几乎)以并发安全的方式(使用任何索引)均匀地拆分表。或者这不在桌面上?顺便说一句,为什么不是经典的partitioning? (在 PostgreSQL 中,您实际上可以查询单个分区。)——没关系,我明白了:客户端数量可能会有所不同。
-
@pozs 硬假设是在查询表时没有写入表,因为这两个进程在工作流中按顺序运行。 BRIN 看起来非常适合该用例:加载数据、创建 brin、分析表,然后运行查询。
-
问:所有(客户端)机器都知道你开始的那一刻应该有多少个分区吗?换句话说,假设您在第 n 天使用 x 台机器开始该过程,您希望您的表均匀地分布在 x 个分区上,对吗?但是在第 x+1 天,您可能拥有 y 台机器,因此希望将其拆分为 y 个分区。那么我的问题是:当客户端机器连接时,它是否知道它想要 1/x 或 1/y 的表?
-
@deroby 不,在客户端内部只有一个唯一的整数序列,所以他们只知道选择哪个存储桶。需要在数据库端提供存储桶。主客户端进程知道有多少节点,因此可以创建表作为选择和计算存储桶,但这与使用底层 brin 分区相比似乎效率低下。
标签: sql postgresql postgresql-9.5