0

2 つのテーブルからデータを取得するクエリがあります。

table1table1_id主キーであるint フィールドがあります。

table22 つのフィールドがあります。table1_id、int フィールド ( を参照table1.table1_id)、およびfield1、ビット フィールド。

table2:table1_idとには 3 つのインデックスがありますfield1(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) 

このクエリのプラン ( を使用して取得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    

以前 (29858) よりも多くの行 (98913) を検索するようになり、元のクエリで以前に使用していたインデックスを使用しなくなりました (field1代わりにtable1_id_field1.

私の質問は次のとおりです。

  1. 追加の句を含む 2 番目のクエリが、最初のクエリで使用していたインデックスを使用していない理由はありますか?

  2. を使用する以外に、mysql により効率的なインデックスを選択させる方法はありますFORCE INDEXか? 多分私は別のインデックスを追加する必要がありますか?

4

1 に答える 1

0

冗長なインデックスが多すぎるとオプティマイザが混乱するため、間違ったインデックスが選択されると思います。

table2 にはインデックスが 1 つあれば十分であるように思えます。table1_id_field1これtable1_idは先頭の列であるため、このインデックスは FK の強制に使用できます。したがって、上のインデックスは必要ありませんtable1_id。インデックスのインデックスは、field1(ビット フィールド上にあるため) 効率的に選択することはできません。

于 2012-08-03T16:26:16.423 に答える