问题描述
早上好,
我正在考虑如何轻松有效地编写它
所以我有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)
上建立索引。