2015-02-07 61 views
0

我有一個客戶希望我爲他的網站做一個後端。他需要一張表格來顯示所有帶分頁的文件。如何優化排序和限制?

CREATE TABLE `content_files` (
    `id` varchar(16) NOT NULL, 
    `owner` varchar(16) DEFAULT NULL, 
    `location` varchar(16) NOT NULL, 
    `parent` varchar(16) DEFAULT NULL, 
    `date` int(11) NOT NULL, 
    `filename` varchar(256) NOT NULL, 
    `username` varchar(64) NOT NULL, 
    `email` varchar(256) NOT NULL, 
    `ip` varchar(15) NOT NULL, 
    `json` text NOT NULL, 
    `bin` blob NOT NULL 
); 

ALTER TABLE `content_files` 
    ADD PRIMARY KEY (`id`), 
    ADD UNIQUE KEY `ID` (`id`), 
    ADD KEY `id_2` (`id`), 
    ADD KEY `date` (`date`), 
    ADD KEY `filename` (`filename`(255)), 
    ADD KEY `username` (`username`(63)), 
    ADD KEY `email` (`email`(255)), 
    ADD KEY `ip` (`ip`(14)); 

需要排序的項目是日期,文件名,用戶名,電子郵件和IP。目前有65,000條記錄。如果極限高,如預期的那樣需要更長的時間,但是它非常長。 100秒獲得第60,000條。

我只是用:

SELECT id, date, filename, username, email ip 
FROM content_files 
ORDER BY filename 
LIMIT 60000, 20 

找遍了這個問題,但是,沒有任何提示似乎改善我的查詢。在他的模式中是否有一些明顯的錯誤?我怎樣才能優化這個?

+0

InnoDB?顯示'EXPLAIN'結果。 – 2015-02-07 18:54:10

回答

0

您正在構建一個大數據集並對其進行排序,僅丟棄60K行並顯示20行。該行爲可以通過所謂的延遲加入來減少。排序仍然必須發生,但它可能需要更少的內存,因此速度更快。

編輯將子查詢獲取到連接中。

SELECT a.id, a.date, a.filename, a.username, a.email ip 
    FROM content_files a 
    JOIN ( SELECT id 
       FROM content_files 
      ORDER BY filename 
      LIMIT 60000, 20 
     ) b ON a.id = b.id 
    ORDER BY a.filename 

這是你的偉大的排序 - 在較小的數據集上丟棄操作。然後它會查找20行所需的所有數據。

最後,如果您在(filename, id)上添加複合索引,則可以通過掃描索引來滿足子查詢,從而使索引更快。創建複合索引時,您可以刪除filename上的索引。

你的桌子上有一堆冗餘索引。 (僅在id單獨三個)。清理你的索引!他們放慢更新速度。

+0

服務器正在使用的MySQL版本(5.6.2)不允許IN語句中的LIMIT。 此外,這個模式不是我自己提到的。我不確定是否明確使用了其他ID索引。在刪除之前,我正在等待之前的開發人員的輸入。 – 2015-02-07 20:02:31

+0

對不起'IN(LIMIT ...)'的錯誤。我已將其更改爲「JOIN」。 – 2015-02-07 21:10:38