使用'in子句'提高[mysql查询]的性能

时间:2012-08-03 16:14:28

标签: mysql performance explain

我有一个查询从两个表中检索数据。

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**

查询不再像以前那样使用高效的索引;这是查询计划:

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. 除了使用FORCE INDEX之外,有什么方法可以让mysql选择更高效的索引?也许我需要添加另一个索引?

1 个答案:

答案 0 :(得分:0)

我猜想有太多的冗余索引会使优化器混淆,所以选择了错误的索引。

在我看来,在table2上只有一个索引table1_id_field1就足够了,因为table1_id是一个前导列,所以这个索引可用于强制执行FK;因此,不需要table1_id上的索引。 field1上的索引不能选择(因为它在位字段上)是有效的。