Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
优化PSQL查询的执行时间_Sql_Postgresql_Postgresql Performance - Fatal编程技术网

优化PSQL查询的执行时间

优化PSQL查询的执行时间,sql,postgresql,postgresql-performance,Sql,Postgresql,Postgresql Performance,这是我第一次遇到query执行时间长的问题。这个问题实际上相当大,因为查询的执行时间超过20秒,这对于端点用户来说非常明显 我有相当大的主题数据库(~8k),主题有它的参数(这是字典-我有113个不同的参数用于8k主题) 我想展示一下关于这些主题重复次数的报告 topic table: ----------------+---------+----------------------------------------------------- id | integer

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

我有相当大的
主题数据库
(~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

有什么方法可以优化此查询的执行时间吗?

简单的分组成员也应该做同样的事情(如果我正确理解了您的查询)

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
对于一个列来说是一个可怕的名称。一个原因是它也是一个保留字,但更重要的是它没有记录该列包含的内容。一个“开始日期”、“结束日期”、“截止日期”、“记录日期”、“发布日期”,…?

对于我来说,不同的
+
子查询
正在扼杀你的性能。
您应该以两种方式使用
groupby
“取消”您的数据和“计数”

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

在这种情况下,使用
topicparam.id
topic.id

删除从不在联接子句中使用的列上的索引


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

您可以尝试以下查询:

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

请发布
explain analyze
(或上传到)。表中定义了哪些索引?您使用的是哪个确切的Postgres版本?请阅读并适当编辑您的问题。tp.name上的max()没有任何意义。max()或min()在日期上获取第一个主题日期或最后一个主题日期(如果有不同的日期)可能很有趣,但根据原始查询,似乎不是这样。@Ryx5:原始查询使用了一个
distinct
,这似乎表明OP只需要一些独特的组合。它看起来确实像是试图获取群组所做的事情,但作为原始查询所有的问题都缺少很多我必须猜测的必要信息。就像你在答案中所做的那样,它可以是所有列上的一组。
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