2013-03-19 232 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