优化Postgresql查询

时间:2012-03-20 04:08:41

标签: 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的示例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的顺序。如果这在计算上很昂贵,可能在客户端代码中我会尝试优化它。但我不确定它会有多高效。

由于

1 个答案:

答案 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_idt1.tr_id保持未分类。

索引

显然,您需要t2.query_idCREATE 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}}

关于performance tuning in the Postgres Wiki的更多建议。