2012-10-25 52 views
3

我有一張拒絕使用索引的表,它總是使用filesort。MySQL在索引化的TIMESTAMP列上使用filesort

表是:

 
CREATE TABLE `article` (
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `Category_ID` int(11) DEFAULT NULL, 
    `Subcategory` int(11) DEFAULT NULL, 
    `CTimestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `Publish` tinyint(4) DEFAULT NULL, 
    `Administrator_ID` int(11) DEFAULT NULL, 
    `Position` tinyint(4) DEFAULT '0', 
    PRIMARY KEY (`ID`), 
    KEY `Subcategory` (`Subcategory`,`Position`,`CTimestamp`,`Publish`), 
    KEY `Category_ID` (`Category_ID`,`CTimestamp`,`Publish`), 
    KEY `Position` (`Position`,`Category_ID`,`Publish`), 
    KEY `CTimestamp` (`CTimestamp`), 
    CONSTRAINT `article_ibfk_1` FOREIGN KEY (`Category_ID`) REFERENCES `category` (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=94290 DEFAULT CHARSET=utf8 

查詢是:

 
SELECT * FROM article ORDER BY `CTimestamp`; 

的解釋是:

 
+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra   | 
+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+ 
| 1 | SIMPLE  | article | ALL | NULL   | NULL | NULL | NULL | 63568 | Using filesort | 
+----+-------------+---------+------+---------------+------+---------+------+-------+----------------+ 

當我刪除了 「ORDER BY」,那麼所有工作正常。所有其他指數(子類別,職位等)在其他查詢中工作正常。不幸的是,時間戳拒絕使用,即使使用我的簡單選擇查詢。我確信我在這裏錯過了一些重要的東西。

如何讓MySQL使用時間戳索引?

謝謝。

+0

當您嘗試創建索引並放置您嘗試創建索引的代碼時,會出現什麼錯誤(在我的網絡中,ajax被阻止,因此我不能在那裏發表評論,這就是爲什麼我在這裏問)。 –

回答

5

在這種情況下,MySQL沒有使用您的索引進行排序,這是一件好事。 爲什麼?你的表只包含64k行,平均行寬約26字節(如果我添加了列大小的權利),所以磁盤上的表總大小應該在2MB左右。 從磁盤讀取2MB數據到內存(可能只需1-2次磁盤操作或尋道),然後只是在內存中執行filesort(可能是quicksort的變化)是非常便宜的。

如果MySQL按照您的意願通過索引順序進行檢索,則必須執行64000次磁盤查找操作,一個接一個地記錄!這本來會非常非常緩慢。

當您可以使用它們快速跳轉到大文件中的已知位置並讀取少量數據時(如在WHERE子句中),索引可以很好。但是,在這種情況下,這不是個好主意 - 而MySQL並不愚蠢!

如果你的表非常大(超過內存大小),那麼MySQL肯定會開始使用你的索引 - 這也是件好事。

+0

因此'使用filesort'實際上意味着它在內存中完成*?非常令人困惑的名字。 –

+0

是的,它是在大小爲@@ sort_buffer_size的緩衝區中完成的(在我的機器上它是16MB) – mvp

+0

謝謝。如何報告磁盤**上的排序**? (如果sort_buffer_size小於要排序的結果) –

0

那麼,你總是可以提示索引。將您的查詢更改爲

SELECT * FROM article use index (CTimestamp); 

這會強制MySQL使用索引進行查詢。解釋:

1, 'SIMPLE', 'article', 'ALL', '', '', '', '', 1, 100.00, '' 

沒有要查看的文件,因爲使用的索引是CTimestamp,結果應該相應地排序。

或者,您可以通過子句保持您的訂單,但強制使用索引:

SELECT * FROM article force index (CTimestamp) order by CTimestamp; 

的問題仍然是陌生的,雖然。你有沒有考慮過把它發佈到官方的MySQL幫助論壇?

編輯:你好像是in good company
編輯:強制索引seems to work out well

相關問題