2011-05-22 47 views
5

表結構:爲什麼MySQL在這種情況下使用filesort?

CREATE TABLE IF NOT EXISTS `newsletters` 
(
    `id` int(11) NOT NULL auto_increment, 
    `last_update` int(11) default NULL, 
    `status` int(11) default '0', 
    `message_id` varchar(255) default NULL, 
    PRIMARY KEY (`id`), 
    KEY `status` (`status`), 
    KEY `message_id` (`message_id`), 
    KEY `last_update` (`last_update`) 
) 
ENGINE=MyISAM DEFAULT CHARSET=latin1; 

查詢:

SELECT id, last_update 
FROM newsletters 
WHERE status = 1 
ORDER BY last_update DESC 
LIMIT 0, 100 
  • newsletters表有超過300萬條記錄
  • 查詢接管26秒執行

查詢說明:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE newsletters range status status 5 NULL 3043354 Using where; Using filesort 

那麼爲什麼不使用filesort,以及它是如何一個range查詢?

回答

5

它使用filesort來排序last_update。您可以通過將索引更改爲status, last_update來避免這種filesort,因此MySQL會以正確的順序查找狀態爲1的所有行。

要進一步優化,請將索引更改爲status, last_update, id。這樣MySQL就可以通過查看索引來滿足查詢,而無需查找表。

CREATE INDEX idx_newsletters_status 
ON newsletters(status, last_update, id); 
+0

KEY應該應用與INDEX相同的索引。 – 2011-05-22 08:17:36

+0

這樣做,我是一個業餘的優化/索引,所以我沒有真正考慮嘗試索引多個列。 @Baez:你能說說你的意思嗎? – HyderA 2011-05-22 08:23:19

+1

@gAMBOOKa:爲了想象什麼樣的索引對你最有幫助,試着想一下列表,按照什麼順序最能幫助_you_如果你是電腦,並且必須快速找到正確的記錄,並返回詢問信息。在這種情況下,您需要一個所有記錄的列表(因爲每個索引需要是所有記錄)按狀態排序(因爲您只對1s感興趣),然後按last_update排序(這樣您可以快速獲得前100名)。如果您將該ID添加到列表中,那麼您可以獲取所有信息而無需返回主表。 – Avi 2011-05-22 10:32:33

相關問題