2012-02-08 45 views
2

的問題MySQL的使用上大表不正確的索引

我有一個表,這是大約200萬行(115 MB),它是關於要大得多。當在桌面上運行一些實用程序腳本時,我發現我的一個查詢需要很長時間(15+秒),而幾乎相同的查詢在之前不到半秒。下面是查詢:

查詢1:

SELECT `id` FROM `my_table` WHERE `my_column`='test' ORDER BY `id` LIMIT 28000, 1000 
Execution time: 0.204 seconds 

查詢2:

SELECT `id` FROM `my_table` WHERE `my_column`='test' ORDER BY `id` LIMIT 29000, 1000 
Execution time: 10.203 seconds 


索引和表信息

id是一個主鍵,my_column也索引(雖然目前它的基數我只有S1)

• ID是一個i​​nt
• my_column是一個varchar(50)

查詢解釋

查詢1:類型:索引,possible_keys :my_column,key:PRIMARY,key_len:4,:29000,額外:使用其中

問題2:類型:範圍,possible_keys:my_column,:my_column,key_len:行 :2,139,123 額外:使用where;使用filesort

正如你可以看到第二個查詢使用my_column鍵和文件並永久使用,但我所做的只是將極限偏移量增加1,000。

如何暫時解決了這一問題

1)如果我刪除WHERE my_column = 'test'條件MySQL優化正確使用主鍵進行排序,但我不能刪除這個條件,因爲很快會有其他在my_column中我需要爲這個查詢過濾掉這些值。 2)如果我使用FORCE INDEX (PRIMARY),mysql優化器也會使用正確的索引,但這似乎是一種破解。

我的問題

究竟爲什麼mysql的選擇使用my_column指數,而不是主鍵的?有沒有更好的方法來處理這個在表定義,索引或我的查詢結構?

回答

3

我會嘗試在(my_column, id)的組合上創建一個composite index

+0

嘆息......我只是喜歡愚蠢的疏忽。感謝您的幫助 – Jeff 2012-02-08 21:53:46

0

這很奇怪。你有沒有嘗試添加一個複合索引?

ALTER TABLE `my_table` ADD INDEX (id, my_column); 

如果您只是選擇id並且始終只使用where子句中的my_column,那麼這應該很好。

+0

您希望'my_column'成爲組合索引的最左列,因爲它是在WHERE子句中測試的那個列。 – 2012-02-08 21:54:55

0

隨着您目前的設置,有兩種明顯的方式來執行查詢。

  1. 檢索id訂單中的行並丟棄與WHERE子句不匹配的行。
  2. 檢索與WHERE子句匹配的行,並按照id的順序對它們進行排序。

推測MySQL猜測根據你想要的行數來決定使用哪種方式。

但是,如果你創建兩個my_columnid索引,MySQL能夠然後retrive行中my_column, id順序,開始於第一行,其中my_column = 'test'

請注意,在一般情況下,這要求WHERE子句中的所有條件均相等,並且WHERE子句中的所有列都存在於索引中。