2012-08-03 31 views
0

我有一個查詢從兩個表中檢索數據。使用'in子句'提高[mysql查詢]的性能

table1有一個int字段,table1_id這是主鍵。

table2有兩個字段; table1_id,int字段(其參考table1.table1_id)和field1,位字段。

上有table2三個指標:table1_idfield1table1_id_field1(該指數是由名稱所指示的字段)。

我有以下查詢:

SELECT * FROM table1 t1 
LEFT JOIN table2 t2 
ON t2.table1_id = t1.table1_id 
WHERE t2.table1_id IN 
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) 

此查詢的計劃(通過使用EXPLAIN獲得)是這樣的:

id select_type table type possible_keys      key    key_len ref    rows Extra 
1 SIMPLE  t2  range table1_id,field1,table1_id_field1 table1_id_field1 8  NULL    29858 Using where 
1 SIMPLE  t1  eq_ref PRIMARY       PRIMARY   8  db1.t2.table1_id 1  

現在,當我添加一個額外的where子句於該查詢,像這樣:

SELECT * FROM table1 t1 
LEFT JOIN table2 t2 
ON t2.table1_id = t1.table1_id 
WHERE t2.table1_id IN 
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) 
**AND field1 = 0** 

查詢不再使用與befo一樣有效的索引回覆;這裏是查詢計劃:

id select_type table type  possible_keys      key  key_len ref    rows Extra 
1 SIMPLE  t2  ref  table1_id,field1,table1_id_field1 field1 2  const    98913 Using where 
1 SIMPLE  t1  eq_ref PRIMARY       PRIMARY 8  db1.t2.table1_id 1  

現在搜索比以前更多的行(98913),(29858),並且不再使用它是在原來的查詢使用前指數(它使用field1代替。table1_id_field1

我的問題是:

  1. 是否有一個原因,隨着附加條款的第二個查詢沒有使用它是使用在第一個查詢索引

  2. 有什麼辦法可以讓mysql選擇更高效的索引,除了使用FORCE INDEX?也許我需要添加另一個索引?

+0

第二個查詢比較慢嗎? – 2012-08-03 16:59:58

回答

0

我猜測有太多的冗餘索引混淆了優化器,所以選擇了錯誤的。

在我看來,對於table2,table1_id_field1只需要一個索引就足夠了,因爲table1_id是一個領先的列,所以這個索引可以用於強制FK;因此,不需要索引table1_idfield1上的索引不能有選擇性(因爲它在位域上)是有效的。

+0

我會嘗試刪除其他索引並查看會發生什麼。 – 2012-08-03 20:21:00