2013-03-13 115 views
1

我有它運行很慢(幾乎50000條記錄)以下查詢如何優化這個慢速查詢?

SELECT 
    news.id, 
    news.title, 
    DATE_FORMAT(news.date_online,'%d %m %Y')AS newsNL_Date 
    news_categories.parent_id 
FROM 
    news, 
    news_categories 
WHERE 
    DATE(news.date_online)=2013-02-25 
    AND news.category_id = news_categories.id 
    AND news.date_online < NOW() 
    AND news.activated ='t' 
ORDER BY 
    news.date_online DESC 

我有MySQL客戶端版本5.0.96

當我運行EXPLAIN EXTENDED調用這個查詢,這是結果:

 
id select_type table    type  possible_keys      key   key_len  ref    rows  Extra 
1  SIMPLE  news    ref  category_id,date_online,activated activated 1   const    43072 Using where; Using filesort 
1  SIMPLE  news_categories eq_ref PRIMARY,id       PRIMARY  4   news_category_id 1  

我有以下列的索引 news_id(主鍵) date_online 激活 美食gory_id

當我看看EXPLAIN EXTENDED結果時,我看到了USING_WHERE;使用FILESORT。我知道他們兩人都不好,但我不知道如何解決這個問題。

回答

-1

您的查詢獲取數據特定日期,所以在這種情況下,你可以省略AND news.date_online < NOW()一部分(可能是查詢優化器可以實現這個要求)。

在另一種情況下,如果您希望所有活動消息沒有指定date_online,那麼您也應該除去NOW()。問題是,你的查詢不能被數據庫緩存,因爲它包含每個執行都不同的部分(NOW())。你可以通過在那裏提供一個計算的常量來做到這一點如果您在比較過程中忽略了分鐘部分,則可以將其緩存到最大值。 60秒。

接下來,您應該爲您正在使用的列創建多列索引,因爲我猜category_iddate_onlineactivated幾乎用於每個查詢。這會使插入速度稍慢,但從它看起來像(新聞應用程序)將有更多的讀取比插入。

1

嘗試爲date_online(B型樹)添加索引。另外我會盡量避免在close處使用NOW(),而是將其設置在一個變量中,然後使用該變量。

我想id字段是鍵,所以他們已經索引。

+0

謝謝,我已經得到了一個date_online的索引 – user1169366 2013-03-13 12:08:48

+0

date_online上的索引被忽略,因爲您不是直接使用該列,而是對該列的值執行函數並比較結果 – Kickstart 2013-03-13 13:13:53

1

使用LEFT JOIN,看到了差距

SELECT 
    news.id, 
    news.title, 
    DATE_FORMAT(news.date_online,'%d %m %Y')AS newsNL_Date 
    news_categories.parent_id 
FROM 
    news 
LEFT JOIN news_categories ON news_categories.id = news.category_id 
WHERE 
    DATE(news.date_online)= '2013-02-25' 
    AND DATE(news.date_online) < DATE(NOW()) 
    AND news.activated ='t' 
ORDER BY 
    news.date_online DESC 
1

除了其他有價值的建議,你有DATE(news.date_online)= 2013-02-25。這似乎迫使MySQL將news.date_online轉換爲表格中每一行的不同格式。這將停止索引有用。

可能將其更改爲news.date_online BETWEEN'2013-02-25 00:00:00'AND'2013-02-25 23:59:59'這應該(我認爲)允許date_online上的索引要使用