0

这是我第一次遇到query执行时间长的问题。问题实际上相当大,因为查询执行时间超过 20 秒,这对端点用户来说非常明显。

我有相当大的topics(~8k)数据库,主题有它的参数(这是字典 - 我有 113 个不同的参数用于 8k 主题)。

我想展示关于这些主题的重复次数的报告。

topic table:
----------------+---------+-----------------------------------------------------
 id             | integer | nextval('topic_id_seq'::regclass)
 topicengine_id | integer |
 description    | text    |
 topicparam_id  | integer |
 date           | date    |

topicparam table:
----------------+---------+----------------------------------------------------------
 id             | integer | nextval('topicparam_id_seq'::regclass)
 name           | text    |

和我的查询:

select distinct tp.id as tpid, tp.name as desc, (select count(*) from topic where topic.topicparam_id = tp.id) as count, t.date
from topicparam tp, topic t where t.topicparam_id =tp.id

Total runtime: 22372.699 ms

结果片段:

 tpid |                     topicname               | count |    date
------+---------------------------------------------+-------+---------
 3823 | Topic1                                      |     6 | 2014-03-01
 3756 | Topic2                                      |    14 | 2014-03-01
 3803 | Topic3                                      |    28 | 2014-04-01
 3780 | Topic4                                      |  1373 | 2014-02-01

有没有办法优化这个查询的执行时间?

4

3 回答 3

1

一个简单的 group by 应该做同样的事情(如果我正确理解了您的查询。

select tp.id as tpid, 
       max(tp.name) as desc, 
       count(*) as count, 
       max(t.date) as date
from topicparam tp
  join topic t on t.topicparam_id = tp.id
group by tp.id;

顺便说一句:date是一个可怕的列名称。一个原因是因为它也是一个保留字,但更重要的是因为它没有记录该列包含的内容。“开始日期”、“结束日期”、“截止日期”、“记录日期”、“发布日期”……?

于 2014-04-08T06:11:22.553 回答
0

对我来说DISTINCT+SUBQUERY正在扼杀你的表现。您应该同时使用GROUP BY两种方式来“区分”您的数据和“计数”。

SELECT 
    tp.id as tpid
    , tp.name as description
    , count(*) as numberOfTopics
    , t.date
FROM 
    topicparam tp
    INNER JOIN topic t 
        ON t.topicparam_id = tp.id
GROUP BY
    tp.id 
    , tp.name
    , t.date

考虑到大量数据,您必须注意索引:

在这种情况下,使用索引topicparam.idtopic.id

删除从未在连接子句中使用的列上的索引。

尽量不要对别名或表字段使用 sql 保留字,如“date、desc、count”。

于 2014-04-08T06:13:16.023 回答
0

你可以试试这个查询:

SELECT tp.id AS tpid,
       tp.name AS DESC,
       topic.cnt AS count,
       t.date
FROM topicparam tp
JOIN topic t
  ON t.topicparam_id =tp.id
JOIN (SELECT topicparam_id,
             count(*) cnt 
      FROM topic
      GROUP BY topicparam_id) topic
  ON topic.topicparam_id = tp.id
GROUP BY tp.id,
         tp.name,
         t.date,
         topic.cnt
于 2014-04-08T06:15:34.577 回答