找到所有帖子,其中宾客最后发表评论,昨天发表

问题描述

早上好,

我正在考虑如何轻松有效地编写它

所以我有Posts表(id,user_id,created_at)和Comments表(id,user_id,post_id,created_at)。 我需要找到所有来自来宾用户(user_id为NULL)和昨天起最后评论的帖子。因此,这些帖子不应有今天的评论,而应至少有昨天的评论。来宾用户添加昨天的 LAST 评论(此后无其他评论)。

我能够得到所需的信息,但是很难编写能够有效执行的智能查询。结果中的估计记录数超过1k(我们每天有成千上万的新帖子和上万的新评论)。

在created_at字段上添加索引是否有意义,也许我必须以某种方式对数据进行非规范化才能获得良好的结果(最坏情况下最长500毫秒)

欢迎任何想法。

谢谢。

解决方法

您没有显示当前查询。一种选择是使用横向联接来编写此联接,该联接将根据post_id检索最后一条注释,然后在where子句中使用过滤器:

select *
from posts p
cross join lateral (
    select c.*
    from comments c
    where c.post_id = p.id
    order by c.created_at desc limit 1
) c
where c.user_id is null

此查询应利用comments(post_id,created_at desc,user_id)(或可能为comments(post_id,user_id))上的索引。

我们还可以尝试使用distinct on预先过滤评论表:

select *
from posts p
inner join (
    select distinct on (post_id) *
    from comments 
    order by post_id,created_at desc
) c on c.post_id = p.id
where c.user_id is null
,

您是否考虑过使用EXPLAIN ANALYZE?这应该可以帮助您调查添加索引是否可以缩短查询时间,尽管如果您之前没有使用过索引,那么毫无疑问,您需要花费一些时间来学习如何使用它。

,

如果您正在寻找帖子以提高效率,我建议:

select c.post_id
from (select distinct on (post_id) c.*
      from comments c
      where c.created_on >= current_date - interval '1 day'
      order by post_id,created_on desc
     ) c
where c.created_on < current_date and
      c.user_id is null;

为此,您需要在comments(created_on,post_id)上建立索引。