假设我有两张桌子,新闻和评论。
news (
id,
subject,
body,
posted
)
comments (
id,
parent, // points to news.id
message,
name,
posted
)
我想创建一个查询来抓取最新的x#新闻项目以及每个新闻帖子的最新评论的名称和发布日期。
速度在选择子查询中的所有注释方面都很重要。
答案 0 :(得分:3)
我刚刚意识到如果没有附加到新闻表的评论,查询就不会返回结果,这里是修复以及总帖子数量的添加列:
SELECT news.*, comments.name, comments.posted, (SELECT count(id) FROM comments WHERE comments.parent = news.id) AS numComments
FROM news
LEFT JOIN comments
ON news.id = comments.parent
AND comments.id = (SELECT max(id) FROM comments WHERE parent = news.id)
答案 1 :(得分:1)
如果速度非常重要,为什么不创建一个包含最新注释的id和parent id的recent_comment表?每次在新闻帖子上发布评论时,请替换该新闻ID的最新评论ID。在新表的新闻ID列上创建一个索引,你的连接速度很快。
你的写入速度是读取速度,但不是很多。
答案 2 :(得分:1)
假设已发布是唯一的时间戳,否则请选择唯一的自动编号
select c.id, c.parent, c.message, c.name, c.posted
c.message, c.name,
c.posted -- same as comment_latest.recent
from comments c
join
(
select parent, max(posted) as recent
from comments
group by parent
) as comment_latest
on c.parent = comment_latest.parent
and c.posted = comment_latest.recent
完成(显示新闻信息):
select
n.id as news_id, n.subject, n.body, n.posted as news_posted_date
c.id as comment_id,
c.message, c.name as commenter_name, c.posted as comment_posted_date
from comments c
join
(
select r.parent, max(r.posted) as recent
from comments r
join
(
select id from news order by id desc limit $last_x_news
) news l
on r.parent = l.id
group by r.parent
) as comment_latest
on c.parent = comment_latest.parent
and c.posted = comment_latest.recent
join news n on c.parent = n.id
<小时/> 注意:强>
上面的代码不是子查询,而是表派生查询。它比子查询更快。这是子查询(慢):
select
id,
subject,
body,
posted as news_posted_date,
(select id from comments where parent = news.id order by posted desc limit 1) as comment_id,
(select message from comments where parent = news.id order by posted desc limit 1) as message,
(select name from comments where parent = news.id order by posted desc limit 1) as name,
(select posted from comments where parent = news.id order by posted desc limit 1) as comment_posted_date,
from news
答案 3 :(得分:1)
SELECT news.subject, news.body, comments.name, comments.posted
FROM news
INNER JOIN comments ON
(comments.parent = news.id)
WHERE comments.parent = news.id
AND comments.id = (SELECT MAX(id)
FROM comments
WHERE parent = news.id)
ORDER BY news.id
这会获取所有新闻项目,以及具有最高id值的相关评论,理论上这应该是最新的。
答案 4 :(得分:1)
我的解决方案类似于 J ,但我认为他添加了一行不必要的内容:
SELECT news.*, comments.name, comments.posted FROM news INNER JOIN comments ON news.id = comments.parent WHERE comments.id = (SELECT max(id) FROM comments WHERE parent = news.id )
虽然不确定超大桌子上的速度。
答案 5 :(得分:0)
鉴于我在其他答案的评论中所揭示的限制,我有一个新的想法,在实践中可能有或没有任何意义。
使用以下定义创建一个视图(或更合适的函数),名为recent_comments:
SELECT MAX(id), parent
FROM comments
GROUP BY parent
如果父列上有聚簇索引,这可能是一个相当快的查询,但即便如此,它仍然是一个瓶颈。
使用此功能,您需要获得答案的查询类似于
SELECT news.*, comments.*
FROM news
INNER JOIN recent_comments
ON news.id = recent_comments.parent
INNER JOIN comments
ON comments.id = recent_comments.id
另外还有对没有任何评论的新闻帖子的考虑。
答案 6 :(得分:0)
我认为@Jan提供的解决方案是最好的。即创建“View”并使用SQL语句将其连接起来。
这肯定会减少提取数据的时间。我测试了它,它100%工作。