问题描述
我在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_processes
和max_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')));