我有两个表,我必须查询我的 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 的示例数据库为
1 25 96
2 28 97
3 27 98
4 26 99
table2 的示例数据库为
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 block 进行查询的查询。在 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 第二代处理器和 8GB RAM。
以下是我的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}
即根据table1中存在的queryid的顺序按tr_id排序。如果这在计算上很昂贵,可能在客户端代码中,我会尝试优化它。但我不确定它的效率如何。
谢谢
最佳答案
查询
我希望 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);
服务器配置
如果这是专用数据库服务器,您可以进一步提高 efficient_cache_size
的设置。
@Frank 已经就 work_mem
提供了建议。我引用the manual :
Note that for a complex query, several sort or hash operations might be running in parallel; each operation will be allowed to use as much memory as this value specifies before it starts to write data into temporary files. Also, several running sessions could be doing such operations concurrently. Therefore, the total memory used could be many times the value of work_mem;
它应该足够大,以便能够在 RAM 中对查询进行排序。 10 MB 足以一次容纳 10000 行。如果您的查询一次需要更多,请将其设置得更高。
如果专用数据库服务器上有 8 GB,我很想将 shared_buffers
设置为至少 2 GB。
shared_buffers = 2GB
effective_cache_size = 7000MB
work_mem = 10MB
关于sql - 优化 Postgresql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9781234/