使用JOIN和GROUP BY时重复条目

时间:2017-04-01 16:52:37

标签: mysql database database-schema forum

我试图查询"分页",基本上用线程和帖子表加入用户表以显示论坛页面(范围内的线程)它'应该按每个帖子里面的最后一篇文章排序。我面临的问题是:

  • 线程重复
  • 完成时间太长
  • 最新帖子的用户ID与线程作者ID相同(在这种情况下,线程不会重复)

这是我目前正在使用的查询

SELECT
t.TId AS thread_id,
t.TName AS thread_name,
t.TAuthorId AS thread_author_id,
u2.UName AS thread_author_name,
t.TDeleted AS thread_deleted_boolean,

/* This might slow down things */
(SELECT COUNT(forum_posts.PId) FROM forum_posts WHERE forum_posts.TId = t.TId) AS thread_posts,
(SELECT CEIL(COUNT(forum_posts.PId) / 20) FROM forum_posts WHERE forum_posts.TId = t.TId) AS thread_pages,
/* This might slow down things */


p.PId AS lastpost_id,
FROM_UNIXTIME(p.PDate/1000) AS lastpost_date,
p.PAuthorId AS lastpost_author_id,
u.UName AS lastpost_author_name

FROM forum_posts AS p

LEFT JOIN forum_threads AS t
ON t.TId = p.TId

/*
* Not used
LEFT JOIN forum_users AS u
ON t.TAuthorId = u.UId OR p.PAuthorId = u.UId
*/

LEFT JOIN forum_users AS u
ON p.PAuthorId = u.UId

LEFT JOIN forum_users AS u2
ON t.TAuthorId = u2.UId

ORDER BY p.PId DESC
LIMIT 50

这个比较快,线程作者id和lastpost作者id不同,工作得很好,问题是线程被多次显示(重复)。我试过添加

GROUP BY t.TId

接近结束但它只是使查询永远不会完成加载。

这是索引问题吗?

值得注意的是,如果我可以动态改变我的订单以及我的动态限制,那就太好了。

query += `LIMIT ` + ((page - 1) * (THREADS_SHOWN_PER_PAGE)) + `,` + THREADS_SHOWN_PER_PAGE;

此外,如果用户为空,这不是什么大问题,我在数据库中插入内容的方式有时会在帖子/帖子之后创建用户。

1 个答案:

答案 0 :(得分:0)

如何做论坛......

  • 在线程表中实现last_post_id和post_count(在发布时更新它们)
  • 在(forum_id,last_post_id)
  • 上创建索引

这一点非规范化对性能至关重要。没有它,它将无法工作。 (forum_id,last_post_id)上的索引将允许您通过最后一篇文章对每个论坛中的线程进行排序,这是您通常想要显示的内容。

缓存帖子计数将大大加快您的分页。

显然,由于主题的最后一页访问次数最多,因此当您访问的页面接近结尾而不是主题的开头时,您将显示带有ORDER BY post_id DESC的帖子。相应地调整LIMIT值。

相关问题