0

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

table1有一个 int 字段,table1_id它是主键。

table2有两个字段;table1_id, 一个 int 字段(引用table1.table1_id)和field1, 一个位字段。

table2:table1_idfield1上有三个索引table1_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) 

此查询的计划(通过 using 获得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. 除了使用之外,有什么方法可以让 mysql 选择更有效的索引FORCE INDEX?也许我需要添加另一个索引?

4

1 回答 1

0

我猜想冗余索引过多会使优化器感到困惑,因此它选择了错误的索引。

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

于 2012-08-03T16:26:16.423 回答