2013-03-19 109 views
0

我有两个表:postscategories。 该posts table约有360,000 linesMySQL查询太慢与GROUP BY

我想只显示每个类别的第一篇文章,按日期排序和使用分页。

查询:

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

如果没有太多的类别,也许最好尝试为每个类别写一个查询? – aram90 2013-03-19 17:09:18

+0

查询中没有聚合函数,因此GROUP BY在此上下文中是冗余的。也许你的意思是DISTINCT? – Strawberry 2013-03-19 17:09:38

+0

因为它目前为什么不只是使用SELECT * FROM职位作为临时而不是将第二个SELECT放入? – jonners99 2013-03-19 17:11:28

回答

1

您可以简化您的查询,如下所示:

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

我不知道你是想用子查询来实现。也不确定是否需要GROUP BY,但将它留在那里。

+0

+ 1 - “GROUP BY”将为每个id_category记录返回一条记录。这就是她正在寻找的东西,所以这是必要的。 – Tom 2013-03-19 17:15:55

+0

实际上,每个类别的第一篇文章应该是“ASC”。 – Tom 2013-03-19 17:18:31

+0

我已经试过这种方法,它工作但速度太慢..无论如何,谢谢! :D – 2013-03-19 18:12:02

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); 

这应该给你的每一件产品与最近的职位是产品一起。

CAVEAT

我故意移动LIMIT子句子查询内,以产生正好ID的所需范围。这工作非常非常快!

我已经学会了这种技术的YouTube的视频:http://www.youtube.com/watch?v=ZVisY-fEoMw&feature=share&list=PL0194B59719B45A96

我申请这一个职位的问题,我的回答#:Fetching a Single Row from Join Table

试试看!

+0

我不认为这对演出有所帮助。 – Cfreak 2013-03-19 17:13:35

+0

几乎做到了!加载时间约为10秒。但我注意到,查询每天显示几个帖子。例如:我昨天注册了10个不同类别的产品,它应该首先显示这20个产品,但它只显示了3个.20个不同类别的产品昨天注册了,只显示了6. – 2013-03-19 18:08:44

+0

我有一个错字,它说'GROUP BY id _category'。我将其更改为“GROUP BY id_category”。请再试一次... – RolandoMySQLDBA 2013-03-19 18:10:57

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_categorydate_post上的索引。如果你想考虑的事实超过一个职位可以共享相同的时间戳,我们一个ID,我们需要再添加一个连接。

+0

它的工作,但仍然非常缓慢..看,问题不是我收到的数据,但过程的时间。无论如何谢谢你:D – 2013-03-19 17:57:07

+0

@AllissonFerreira您的查询将通常工作,但没有记录,如果你改变平台或升级你的服务器,它可能会返回错误的数据。你可以做的唯一改善性能的方法就是使用索引。 – fthiella 2013-03-19 18:00:05