sql - 优化 Postgresql 查询

标签 sql postgresql query-optimization

我有两个表,我必须查询我的 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_tokenquery_id 保持未排序。

索引

显然您需要 t1.tr_idt2.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

更多建议performance tuning in the Postgres Wiki .

关于sql - 优化 Postgresql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9781234/

相关文章:

sql - 下载 PostgreSQL Mac 下载错误

oracle - 进行 HASH JOIN 时什么是 HASH TABLE?

mysql - 我怎样才能更好地优化这个查询?

sql - jsonb 在数组中查找一个值

mysql - postgresql vs mysql 易于扩展,以及对高度相关(大量外键)数据库的实用性

python - postgres 数据库 View 上的 Flask Admin

mysql - 如何快速从关系 mysql 表中选择 max(timestamp)

php - $query -> 从用户处获取所有 'friends',有效,但每个 friend 都会获得两倍

mysql - 将多个 MySQL 查询连接在一起

sql - 使用 Date.today 加入命名范围的一部分