2017-02-12 17 views
1

我有一個表進行查詢時,使用Where期間解釋了MySQL查詢

EXPLAIN SELECT `id` 
FROM `tblsender` 
WHERE `userid` = '6' 
AND `astatus` = '1' 
AND `sender` = 'ABCDEF' 

我甚至在所有可能的方式建立索引後得到USING WHERE。這是我的最終表結構代碼。

CREATE TABLE IF NOT EXISTS `tblsender` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`sender` varchar(6) NOT NULL, 
`astatus` tinyint(1) NOT NULL DEFAULT '0', 
`userid` int(11) unsigned NOT NULL, 
PRIMARY KEY (`id`), 
KEY `astatus` (`astatus`), 
KEY `userid` (`userid`), 
KEY `sender` (`sender`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=22975 ; 

我甚至嘗試全文爲sender列,但仍然沒有運氣,我也嘗試過所有where clause列索引。

ALTER TABLE `tblsender` ADD INDEX (`sender` , `astatus` , `userid`) ; 

還在得到using where,我該如何正確索引這張表。

編輯:解釋上述結構的輸出。

id select_type table  type possible_keys   key  key_len  ref  rows Extra 
1 SIMPLE  tblsender ref  astatus,userid,sender astatus  1  const 1  Using where 

,並解釋輸出的所有3列在一起

id select_type table  type possible_keys     key  key_len  ref  rows Extra 
1 SIMPLE  tblsender ref  astatus,userid,sender,sender_2 astatus  1  const 1  Using where 
+1

請參閱:http://stackoverflow.com/questions/9533841/mysql-fix-using-where – zed

+0

當所有三列包含在單個索引中時,Pleaae會顯示來自'EXPLAIN'的輸出。 –

+0

@ Michael-sqlbot,對於遲到的回覆感到抱歉,因爲我有一些互聯網連接問題。我更新了我的問題。 – yuri1000

回答

2

與小數據集進行測試時不能有效地預測對大數據集的優化行爲。

如查詢計劃所示,多列索引被視爲候選人,但優化程序選擇不使用它在這種情況下爲。這並不意味着當它被認爲更有利時它不會使用它。

我只能推測沒有看到你的實際數據集,也許使用optimizer tracing,但我會提供一個合理的推測。

MySQL中的優化器是基於成本的。它試圖以最低成本的方式解決您的查詢。請注意0​​= 1.這意味着優化程序得出結論:至少在統計學上,它預計只有1行將在astatus的索引中匹配。由於key_len = 1,這意味着astatus只有1個字節寬 - 與多列索引相反,11列寬(1 + 6 + 4) - astatus索引看起來像是一個非常便宜的解決方案,所以它決定去那個指數。理論上使用較長的索引意味着更多的I/O,因此成本更高,儘管在這種情況下(由於數據集較小),我們人類認識到成本差異不是特別有意義。

Using where意味着通過使用該索引實際上返回的每一行,服務器將需要驗證該行的WHERE條款的其餘部分相匹配,但是如果我們只希望約1行匹配,這是沒有什麼大的應對。

因此,我建議您不要擔心,因爲當前數據集的小尺寸無法爲您提供預測未來行爲的有用信息。在這種特定情況下,Using where是表格中少量行的人工產物。

您需要更多數據。但是,是的,你確實需要一個多列索引。

+0

我在該表中有22k行。正如你所解釋的,可能where子句只需要返回一行,那麼它不使用索引列。表有192kb的數據,可能你是對的,它只是沒有使用索引。感謝您花時間解釋。 – yuri1000

+0

@ yuri1000如果你首先在桌上運行'ANALYZE TABLE',你也可能得到不同的結果。索引統計信息可能會向優化器提供比理想提示更少的提示。 –