2012-04-15 35 views
2

我有一個表,這個結構(有50K字段):MySQL不與使用ORDER BY指數

CREATE TABLE IF NOT EXISTS `comments` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `imageid` int(10) unsigned NOT NULL DEFAULT '0', 
    `uid` bigint(20) unsigned NOT NULL DEFAULT '0', 
    `content` text CHARACTER SET utf8, 
    `adate` datetime DEFAULT NULL, 
    `ip` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `ids` (`imageid`,`adate`) USING BTREE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=52236 ; 

我想通過圖像標識來選擇數據和ADATE所以我加了(imageid排序, adate)鍵。

但是這個查詢的解釋結果說MuSQL仍然使用表掃描。爲什麼?!

EXPLAIN SELECT comments.* 
FROM comments 
WHERE comments.imageid=50 
ORDER BY 
comments.adate DESC LIMIT 10 

結果:

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE comments ref  ids  ids  4 const 203  Using where 

,並用此指標:

KEY `ids` (`imageid`,`adate`,`id`) USING BTREE 

結果此查詢:

EXPLAIN SELECT comments.id 
FROM comments 
WHERE comments.imageid=50 
ORDER BY 
comments.adate DESC LIMIT 10 

爲:

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE comments ref  ids  ids  4 const 203  Using where; Using index 
+0

您是否有關於imageid的索引? – Arion 2012-04-15 13:32:59

+0

是的,你可以看到我已經添加了一個關鍵的KEY'ID'('imageid','adate')使用BTREE – MscEliot 2012-04-15 13:42:45

+0

如果你在第一個例子中只選擇comments.id,它會有什麼不同嗎? 從我的經驗我可以說:最簡單的方法來檢查這是通過速度。將您的50k條目加倍並搜索某些東西,測量具體和非指標的速度。 – func0der 2012-04-15 14:09:38

回答

0

對於InnoDB創建一個這樣的關鍵(imageid,adate,id);索引中列的順序很重要。

那就試試這個 -

EXPLAIN SELECT comments.id 
FROM comments 
WHERE comments.imageid=50 
ORDER BY 
comments.adate DESC LIMIT 10 

讓我知道什麼是輸出。

感謝您的輸出。 在下面添加以下部分。

如果你需要比ID更多然後嘗試這樣的事情

EXPLAIN 
SELECT c1.* from comments as c1 
JOIN 
(
    SELECT comments.id 
    FROM comments 
    WHERE comments.imageid=50 
    ORDER BY 
    comments.adate DESC LIMIT 10 
) as c2 ON (c1.id=c2.id) 

但這次不靠解釋。無論如何說明仍然會顯示一行。而是在phpmyadmin或mysql查詢瀏覽器中檢查執行時間。

+0

謝謝,我將結果添加到原始問題 – MscEliot 2012-04-15 14:01:49

0

Straight out of the manual:

在某些情況下,MySQL不能使用索引來解決ORDER BY,儘管它仍然使用索引來找到WHERE子句匹配的行。這些情況包括:---在一個鍵的不連續部分使用ORDER BY: SELECT * FROM t1 WHERE key2 =常量ORDER BY key_part2;

也許適用於您的查詢,是因爲你有一個複合KEY ids (imageid,adate),你不要在你的ORDER BY使用imageid。您可以嘗試只爲adate添加密鑰並查看是否有幫助。

1

你是不是正確地解釋結果。

using index意味着查詢是索引覆蓋的 - 數據只能從索引讀取,而實際的行不被使用。這不是因爲索引不同,而是因爲在第二個查詢中,您僅選擇了該ID。

如果MySQL不使用索引來解決ORDER BY,那麼在解釋中將會有using filesort。在這兩個查詢中,使用ids密鑰,並且MySQL 不是 perofrm表掃描

+0

中,你是如此的準確。謝謝。 – 2012-04-15 15:01:51

+0

那麼「使用哪裏」呢?它顯示在兩個查詢中......! – MscEliot 2012-04-15 15:04:06

+0

最有可能的原因是允許空值 – 2012-04-15 15:11:23