Postgresql-HLL的独立计数慢

问题描述

我在Google Cloud sql上有一个数据库,具有4个核心和16GB的RAM。我正在使用postgresql-hll:https://github.com/citusdata/postgresql-hll

我有一个具有以下架构的表:

id domain url_id

id是一个12个字符的字符串,domain是一个字符串,url_id是一个整数。

我的表(名为table1)包含36M行。 我的目标是尽快运行以下类型的查询

SELECT round(#hll_add_agg(hll_hash_text(id))) from table1 where url_id not in (427431,827197,114153,770117,552471,557306) AND ( (domain not in ('domain.com')));

当前,此计数大约需要10000ms。这是计划:

 Aggregate  (cost=1192989.83..1192989.84 rows=1 width=8) (actual time=10611.223..10611.223 rows=1 loops=1)
   ->  Seq Scan on table1  (cost=0.00..1011806.64 rows=36236637 width=13) (actual time=0.022..7373.193 rows=36201573 loops=1)
         Filter: ((domain <> 'domain1.com'::text) AND (url_id <> ALL ('{427431,557306}'::integer[])))
         Rows Removed by Filter: 689666

当前似乎没有任何类型的并行性,即使将数据库规格降低到1核和1Gb ram之后,perf也似乎是相同的。 我的目标是使执行时间至少达到2000ms:是否有明显的方法来实现? 我试图更改数据库上的一些内存参数(我是随机的admin),但是Google Cloud sql标志似乎并不为每个postgresql变量都拥有一个标志。

解决方法

要获得并行化,请将max_worker_processesmax_parallel_workers设置得足够高(4个内核为3个),并将表上的parallel_workers存储参数设置为3个。4个内核,三个以上工作进程无济于事。

除此之外,您只能使用更快的存储空间或足够的RAM来缓存表。

,

HLL扩展不支持并行化。有一个pull request要添加,但是现在已经过时了。我不知道是否有人想再尝试一次。

但是hll的主要用例是它允许重新聚合部分聚合,因此,如果您维护具有部分聚合的物化视图,则可以获得更快的聚合:

create materialized view mv1 as select url_id,domain,hll_add_agg(hll_hash_text(id)) as hll from table1 group by url_id,domain;

select #hll_union_agg(hll) from mv1 where url_id not in (427431,827197,114153,770117,552471,557306) AND ( (domain not in ('domain.com')));