2012-08-03 30 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