我有两个表:posts
和categories
。
posts table
约有360,000 lines
。
我想只显示每个类别的第一篇文章,按日期排序并使用分页。
查询:
SELECT * FROM
(SELECT * FROM posts ORDER BY date_post DESC) as temp
GROUP BY id_category ORDER BY date_post DESC
LIMIT $offset, $limit"
查询大约需要1分钟才能加载并显示我的网站。
我尝试将MyISAM更改为InnoDB并使用分区而不成功。
托管网站的服务器是专用服务器,我认为问题不在于此。
有人有什么建议吗?
答案 0 :(得分:1)
您可以按如下方式简化查询:
SELECT *
FROM posts
GROUP BY id_category
ORDER BY date_post DESC
LIMIT $offset, $limit
我不确定你用子查询想要完成什么。也不确定GROUP BY是否需要,但是把它留在那里。
答案 1 :(得分:0)
您需要重构查询:
SELECT posts.* FROM
(
SELECT id_category,MAX(date_post) date_post
FROM posts GROUP BY id_category
) postkeys LEFT JOIN posts USING (id_category,date_post);
这应该会为您提供每件产品以及该产品的最新帖子。
我故意在子查询中移动LIMIT子句以生成所需的id范围。这非常非常快!!!“
我已经在YouTube视频中学到了这种技巧:http://www.youtube.com/watch?v=ZVisY-fEoMw&feature=share&list=PL0194B59719B45A96
我将此应用于我在StackOverflow中回答的帖子问题:Fetching a Single Row from Join Table
试一试!!!
答案 2 :(得分:0)
您的查询不正确,因为您正在使用non-aggregated columns in a GROUP BY query,并且这些列的值可能未确定(您无法保证您将收到第一篇文章)。
不知道它是否更快,但如果你确定没有多个帖子具有相同的时间戳,你可以使用它:
SELECT posts.*
FROM
posts INNER JOIN (
SELECT
id_category, MAX(date_post) mx_date
FROM
posts
GROUP BY
id_category
) mx ON posts.id_category=mx.id_category
AND posts.date_post=mx.mx_date
ORDER BY
posts.date_post DESC
LIMIT $offset, $limit
请参阅小提琴here。
当然,请确保您在id_category
和date_post
上都有索引。如果你想考虑这个事实而不是一个帖子可以共享相同的时间戳,我们就是一个id,我们需要再添加一个连接。