0

我有两张桌子:postscategories。有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 并使用分区但没有成功。

托管网站的服务器是专用服务器,我相信问题不在于它。

有人有什么建议吗?

4

3 回答 3

1

您可以按如下方式简化查询:

   SELECT * 
   FROM posts
   GROUP BY id_category
   ORDER BY date_post DESC 
   LIMIT $offset, $limit

我不确定你想用子查询完成什么。也不确定是否需要 GROUP BY,但把它留在了那里。

于 2013-03-19T17:11:49.740 回答
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

试试看 !!!

于 2013-03-19T17:12:39.880 回答
0

您的查询不正确,因为您在 GROUP BY 查询中使用了非聚合列,并且这些列的值可能是不确定的(您不能保证您将获得第一篇文章)。

不知道它是否更快,但如果你确定没有多个帖子具有相同的时间戳,你可以使用这个:

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

在此处查看小提琴。

当然,请确保您有一个索引 onid_category和 on date_post。如果你想考虑一个事实,多个帖子可以共享相同的时间戳,我们需要一个 id,我们需要再添加一个 join。

于 2013-03-19T17:26:08.353 回答