2017-12-03 197 views
-2

我有3个表格:users,postslikes。如果帖子在创建后的第一个小时内有5个以上的喜欢,则该帖子被称为热帖。以下是用于查询热门帖子的列表。任何人都可以帮助我改进这个查询(如何索引或重写它)。改善性能postgresql查询

SELECT post.id, 
     post.content, 
     user.username, 
     COUNT(like.id) 
FROM posts AS post 
    LEFT OUTER JOIN users AS user 
     ON post.user_id = user.id 
    INNER JOIN likes AS likes 
     ON post.id = likes.post_id 
     AND likes.created_at - INTERVAL '1 hour' < post.created_at 
GROUP BY post.id, user.username 
HAVING COUNT(like.id) >= 5 
ORDER BY post.created_at DESC; 
+0

@TimBiegeleisen指数:

如果规划器选择嵌套循环连接毕竟,它可能将查询重写是有用的它的工作原理。 http://prntscr.com/hidlsc –

+1

您需要为任何人提供更多信息,以便为您提供任何有价值的见解。例如,你的表定义,任何现有的索引(如果有的话)和'EXPLAIN'的输出。此外,尽量不要用大写字母给表格别名,并删除所有双引号(为了便于阅读)。 – Nicarus

+3

请** [编辑] **您的问题,并为所讨论的表格(包括所有索引)和使用**'explain(analyze,buffers)'**生成的执行计划添加'create table'语句。 [**格式化文本**](http://stackoverflow.com/help/formatting)请,[无屏幕截图](http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload图像-的代码上那么当-要价-A-问题/ 285557#285557) –

回答

1

首先,除非实际上可能有不属于用户的帖子,否则使用内部联接。

假设有大量的帖子和喜欢,最好的连接策略是合并连接或散列连接,PostgreSQL应该自动选择。

对于合并连接,下面的指标可能会有所帮助:

CREATE INDEX ON posts (id); 
CREATE INDEX ON likes (post_id); 

号指数可以用哈希帮助在这种情况下加入。

... AND likes.created_at < post.created_at + INTERVAL '1 hour' 

和创建像

CREATE INDEX ON likes (post_id, created_at);