2013-01-23 52 views
1

我有一個表「t_table1'包含3個字段:MySQL索引的不能使用

`field1` tinyint(1) unsigned default NULL, 
`field2` tinyint(1) unsigned default NULL, 
`field3` tinyint(1) unsigned NOT NULL default ’0′, 

和指數:

KEY `t_table1_index1` (`field1`,`field2`,`field3`), 

當我運行此SQL1:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 0 AND c.field3 = 0 

然後顯示:

Select type: Simple 
tyle: All 
possible key: t_table1_index1 
key: NULL 
key_len: NULL 
rows: 1042 
extra: Using where 

我認爲這是說我的索引在這種情況下是無用的。

但是當我運行這個SQL2:

EXPLAIN SELECT * FROM table1 AS c WHERE c.field1 = 1 AND c.field2 = 1 AND c.field3 = 1 

它表明:

Select type: Simple 
tyle: ref 
possible key: t_table1_index1 
key: t_table1_index1 
key_len: 5 
ref: const, const, const 
rows: 1 
extra: Using where 

它使用我的索引這種情況。 所以請您解釋一下:

  1. 爲什麼SQL1不能使用索引?

  2. 與SQL1,如何編輯索引或重寫SQL以更快地執行?

謝謝!

+0

表中有多少行?如果索引不會縮小返回的行數,則優化器可以根本不選擇使用索引。 –

+0

我的表有1776條記錄。 SQL1返回10條記錄,SQL2返回0條記錄。 你能解釋得更清楚嗎?爲什麼SQL1不使用索引和SQL2使用索引? –

+0

可能是因爲對於這些值,索引不夠有選擇性(它將返回超過1000行)。優化器查看它並決定讀取索引,然後使用結果來獲取行將比僅執行全表掃描更昂貴。在第二個示例中,查詢將只選擇1行。在這種情況下,使用索引然後獲取單行是值得的。 –

回答

0

查詢優化器使用許多數據點來決定如何執行查詢。其中之一是選擇性的指數。要使用索引,需要比表掃描返回更多的磁盤訪問次數,因爲引擎必須讀取索引,然後獲取實際行(除非整個查詢只能通過索引來滿足)。隨着索引選擇性下降(即更多行符合標準),使用該索引的效率下降。在某個時候,全桌面掃描會變得更便宜。

在第二個示例中,優化器能夠確定您提供的值會導致只有一行被提取,因此索引查找是正確的方法。

在第一個示例中,這些值不是非常有選擇性,估計有從1076年返回的1042行。使用索引將導致搜索索引,構建所選行參考列表,然後獲取每行。選擇這麼多的行,使用索引會導致更多的工作,而不僅僅是線條掃描整個表並過濾行。