2012-08-27 25 views
0

我有以下MySQL查詢索引的查詢,但仍在尋找每一行

select points_for_user from items where user_id = '38415'; 

上查詢說明返回此

id select_type table type possible_keys key      key_len ref  rows Extra 
1 SIMPLE  items index NULL   points_for_user_index 2  NULL 1000511 Using index 

的問題是,不應該行的數量遠由於索引而少於表中的行數?

user_id是主索引,所以我試着在points_for_user上創建一個索引,然後再查看每一行。 user_id AND points_for_user上的索引仍然搜索每一行。

我錯過了什麼?

謝謝!

CREATE TABLE IF NOT EXISTS `items` (
    `capture_id` int(11) NOT NULL AUTO_INCREMENT, 
    `id` int(11) NOT NULL, 
    `creator_user_id` bigint(20) NOT NULL DEFAULT '0', 
    `user_id` int(11) NOT NULL, 
    `accuracy` int(11) NOT NULL, 
    `captured_at` timestamp NOT NULL DEFAULT '2011-01-01 06:00:00', 
    `ip` varchar(30) NOT NULL, 
    `capture_type_id` smallint(6) NOT NULL DEFAULT '0', 
    `points` smallint(6) NOT NULL DEFAULT '5', 
    `points_for_user` smallint(6) NOT NULL DEFAULT '3', 
    PRIMARY KEY (`capture_id`), 
    KEY `capture_user` (`capture_id`,`id`,`user_id`), 
    KEY `user_id` (`user_id`,`id`), 
    KEY `id` (`id`), 
    KEY `capture_creator_index` (`capture_id`,`creator_user_id`), 
    KEY `points_capture_index` (`points_for_user`,`creator_user_id`), 
    KEY `points_for_user_index` (`points_for_user`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1008992 ; 

select count(*) from items where user_id = '38415' 

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE captures ref user_munzee_id user_munzee_id 4 const 81 Using index 
+0

這是一個複合索引嗎?你爲什麼用引號指定數字? – zerkms

+0

是的,points_for_user和user_id上的索引是一個複合索引。我不確定你用引號的意思。如果我使用「38415」而不僅僅是38415,那麼這很重要嗎? – Scott

+0

好吧,如果ID是一個數字列,它將被編入索引,而您正在指定要搜索的字符串。 – Adrian

回答

0

MySQL優化嘗試在查詢過程中使用的最好的指標。

在您的第一個查詢中,優化器正在考慮points_for_user_index的最佳選擇,實際上Extra列顯示「使用索引」狀態,這意味着一個「覆蓋索引」。

當一個查詢所需的所有字段(在你的案例中選擇points_for_user來自...)包含在一個索引中時,就會出現「覆蓋索引」,這就避免了訪問完整的mysql數據(.MYD)直接索引訪問(.MYI)

首先,你可以嘗試重建索引樹分析表的

ANALYZE TABLE itemes;

注意事項非常大的表

ANALYZE TABLE分析並存儲爲一個表密鑰分發。 在分析過程中,該表使用InnoDB 和MyISAM的讀鎖鎖定。該聲明適用於InnoDB,NDB和MyISAM表。 對於MyISAM表格,此聲明相當於使用myisamchk --analyze。

如果「問題」仍然存在,你想跳過優化選擇,你可以明確的嘗試強制索引的使用

EXPLAIN SELECT points_for_user FROM items USE INDEX (user_id) WHERE user_id = '38415' 

更多細節:http://dev.mysql.com/doc/refman/5.5/en/index-hints.html

克里斯蒂安

+0

感謝您的回答。在運行ANALYZE並強制索引後,我仍然得到> 1000511的行,當我只應得到幾百個。任何其他想法? – Scott

+0

您可以使用「USE INDEX」和「SHOW INDEXES表項目」的輸出發佈解釋結果嗎? –

+0

我刪除了主要的索引之外的所有索引,並使用EXPLAIN緩慢地添加了新索引,並且工作得很好,以確保他們正在完成他們的工作。 – Scott