我有两个表,我必须查询我的postgresql数据库。表1有大约1.4亿条记录,表2有大约5000万条以下记录。
表1具有以下结构:
tr_id bigint NOT NULL, # this is the primary key
query_id numeric(20,0), # indexed column
descrip_id numeric(20,0) # indexed column
和表2具有以下结构
query_pk bigint # this is the primary key
query_id numeric(20,0) # indexed column
query_token numeric(20,0)
table1的示例db将是
1 25 96
2 28 97
3 27 98
4 26 99
table2的示例db将是
1 25 9554
2 25 9456
3 25 9785
4 25 9514
5 26 7412
6 26 7433
7 27 545
8 27 5789
9 27 1566
10 28 122
11 28 1456
我更喜欢查询,我可以在tr_id块中查询。在10,000的范围内,因为这是我的要求。
我想以下列方式获得输出
25 {9554,9456,9785,9514}
26 {7412,7433}
27 {545,5789,1566}
28 {122,1456}
我尝试了以下方式
select query_id,
array_agg(query_token)
from sch.table2
where query_id in (select query_id
from sch.table1
where tr_id between 90001 and 100000)
group by query_id
我正在执行以下查询,大约需要121346毫秒,当触发了4个这样的查询时,它仍然需要更长的时间。能否请你帮我优化一下。
我有一台机器在Windows 7上运行,带有i7 2nd gen proc,内存为8GB。
以下是我的postgresql配置
shared_buffers = 1GB
effective_cache_size = 5000MB
work_mem = 2000MB
我该怎么做才能优化它。
由于
编辑:如果按照以下格式排序结果会很棒
25 {9554,9456,9785,9514}
28 {122,1456}
27 {545,5789,1566}
26 {7412,7433}
即根据由tr_id排序的table1中存在的queryid的顺序。如果这在计算上很昂贵,可能在客户端代码中我会尝试优化它。但我不确定它会有多高效。
由于
答案 0 :(得分:2)
我希望JOIN
比您目前的IN
条件快得多:
SELECT t2.query_id
,array_agg(t2.query_token) AS tokens
FROM t1
JOIN t2 USING (query_id)
WHERE t1.tr_id BETWEEN 1 AND 10000
GROUP BY t1.tr_id, t2.query_id
ORDER BY t1.tr_id;
这也按要求对结果进行排序。 query_token
query_id
按t1.tr_id
保持未分类。
显然,您需要t2.query_id
和CREATE INDEX t2_query_id_idx ON t2 (query_id);
上的索引
你显然已经有了这个:
t1
CREATE INDEX t1_tr_id_query_id_idx ON t1 (tr_id, query_id);
上的多列索引可以提高性能(您必须测试):
effective_cache_size
如果这是专用数据库服务器,您可以再提高work_mem
的设置。
@Frank已经就shared_buffers
提供了建议。我引用the manual:
请注意,对于复杂查询,可能会进行多次排序或散列操作 并行运行;每个操作都将被允许使用 内存,因为此值在开始写入数据之前指定 临时文件。此外,几个运行会话可能会这样做 同时进行。因此,使用的总内存可能是 很多次work_mem的价值;
它应该足够大,能够在RAM中对查询进行排序。一次可容纳10000行,10 MB就足够了。如果您的查询一次需要更多,请将其设置得更高。
在专用数据库服务器上使用8 GB,我很想将shared_buffers = 2GB
effective_cache_size = 7000MB
work_mem = 10MB
设置为至少2 GB。
{{1}}