2013-07-18 105 views
0

使用的filesort我有很簡單的表:在簡單查詢

CREATE TABLE `navigation` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `parent_id` int(11) unsigned DEFAULT NULL, 
    `title` varchar(255) NOT NULL COMMENT 'Название ссылки', 
    `priority` tinyint(3) NOT NULL COMMENT 'Параметр сортировки' 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

只有41行。我也有非常簡單的查詢:

mysql> EXPLAIN SELECT t.id, t.parent_id, t.title, t.priority FROM navigation t ORDER BY t.priority ASC; 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra   | 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 
| 1 | SIMPLE  | t  | ALL | NULL   | NULL | NULL | NULL | 41 | Using filesort | 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+ 
1 row in set (0.00 sec) 

我該如何避免使用filesort?或者是不可能的? 我已閱讀了很多關於SO的主題,但無法理解正確的答案。 謝謝。

+0

只有41行,你爲什麼在意? – eggyal

+0

因爲我現在只有41行,但是在生產中有很多行。生產服務器(MySQL)也使用filesort。 –

回答

2

我該如何避免使用filesort?或者是不可能的?我已經閱讀了很多關於SO的主題,但無法理解正確的答案。

您需要在priority列的索引:

ALTER TABLE navigation ADD INDEX (priority); 

但是,機會是,MySQL將計算出使用這種指數排序結果最終將超過filesort更貴(因爲前者將涉及順序讀取索引文件以便在表中執行隨機I/O,而後者將涉及順序讀取表並對結果執行內存中排序)。您可以覆蓋這一評估與index hint

SELECT t.id, t.parent_id, t.title, t.priority 
FROM  navigation t FORCE INDEX FOR ORDER BY (priority) 
ORDER BY t.priority ASC; 

一個covering index將完全避免需要讀入表,因此可以立即從僅僅通過索引文件依次行走返回結果;它會因此有可能通過查詢優化器沒有進一步提示選擇:

ALTER TABLE navigation ADD INDEX(priority, id, parent_id, title); 

哪種方法適合你將取決於應用程序的需求,但要記住Knuth的格言:「過早的優化是一切罪惡的根源」。

1

要避免一個文件夾,大多數時候你應該添加一個索引。在你的情況下,這將意味着priority列的索引。你可以這樣做如下:

ALTER TABLE `navigation` ADD INDEX (`priority`); 

注意,即使該指數仍可能是一個文件排序被用作實際上可能比使用索引快。對於41行,可能會出現這種情況,即使定義了索引也是如此。

1

根據this blog postfilesort發生在每次對未索引列進行排序時發生。它與文件系統中發生的實際分類無關。 隨着Erik's answer中的描述,你應該擺脫它。