2012-03-06 9 views
3

私はこの問題は、MySQLがさえI FORCE INDEX(PRIMARY)場合は、インデックスを使用していないこと、である(a、b)はMySQLがWHERE INのコンポジットでインデックスを使用しないのはなぜですか?

SELECT * FROM table WHERE (a, b) IN ((1,2), (2,4), (1,3)) 

PRIMARY KEYを持つテーブルから複合インデックスで複数のレコードを取得しようとしています。
EXPLAIN SELECTにnull possible_keysが表示されます。

なぜ可能な_キーはありませんか? WHERE()IN(()、()) を使用してUNION ALL

  • を使用して

    • を使用してOR
    • :どのような複合キーで複数の行を取得するための最良の方法である

      PS a_b basicly CONCAT(a, '-', b)と、ちょうどその(WHERE a_b = {$id1}-{$id2})を比較です:クエリは

      SELECT * FROM table WHERE (a = 1 AND b = 2) OR (a = 2 AND b = 4) OR (a = 1 AND b = 3) 
      

      おかげで、特定の列にインデックスを付けるの強い希望で

  • 答えて

    1

    をクエリがインデックスからフィールドのみを選択する(またはテーブルが他のフィールドを持っていない場合)は、複合WHERE ... INにより、インデックスが使用される場合は、次の

    SELECT a,b FROM `table` WHERE (a, b) IN ((1,2), (2,4), (1,3)) 
    

    それ以外の場合は、使用されません。 この問題を回避するには、導出問合せを使用することです:

    SELECT t.* FROM (SELECT a, b FROM `table` WHERE (a, b) IN ((1,2), (2,4), (1,3))) AS o INNER JOIN `table` AS t ON (t.a = o.a AND t.b = o.b) 
    

    SELECT EXPLAIN:

    id select_type table type possible_keys key key_len ref rows Extra 
    1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 
    1 PRIMARY t eq_ref PRIMARY PRIMARY 2 o.a,o.b 1 
    2 DERIVED table index NULL PRIMARY 2 NULL 6 Using where; Using index 
    
    0

    に、あなたは新しい列を持つと考えられてきた結果で等しいのですか?

    テーブルごとに1つのPRIMARY列しか指定できません。 「プライマリ」をインデックスに登録することはできませんab

    +0

    を 'CONCAT使用(、 ' - '、b)のそれは失敗することとして、'、私にとっては良い選択肢ではありませんフィールド値に '' - ''があるとします。 私のPRIMARY KEYは複数列なので、 'a'と' b'の両方を含んでいます。 – vearutop

    +0

    'CONCAT(a、 '! - !'、b)' - あなたはその値を使っていますか? :) –

    +0

    私のテーブルには何億ものレコードが含まれていますが、インデックス付きの文字列ではパフォーマンスが向上しないと思います。むしろバッチコンポジットを選択するには、UNION ALLを使用します。 – vearutop

    関連する問題