9

私は次のようなテーブル構造を持っています

comment_id primary key
comment_content 
comment_author
comment_author_url

次のようなクエリを起動すると

explain SELECT * FROM comments  ORDER BY comment_id

結果を次のように出力します

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  comments    ALL     NULL    NULL    NULL    NULL    22563   Using filesort

主キーとして定義したインデックスが見つからないのはなぜですか?

4

2 に答える 2

16

インデックスを使用できないからではありません。これは、インデックスを使用せずにファイルソートを実行する方が高速であるとオプティマイザが判断したためです1。MyiSAM テーブルと InnoDB テーブルでは異なる動作が見られるはずです。

InnoDB はPRIMARYキーをクラスター化されたもの (UNIQUEプライマリが定義されていない場合は最初のキー) として作成します。これは、必要なすべての値がこのクラスター化されたキーと連続した場所にある (クラスター化されたキーはテーブルです) クエリにORDER BY pk使用WHERE pk BETWEEN low AND highできます。 .

MyISAM テーブルには B ツリー インデックスしかないため、クエリがこのインデックスを使用する場合、そのインデックス全体を読み取る必要がありcomment_id、必要な順序で値が含まれます (これは非常に良いことです) が、テーブルも読み取る必要があります。 (あまり良くありません)他のすべての必要な列を取得します。オプティマイザーは、これからテーブルを読み取るので、すべてをスキャンしてファイルソートを実行しないのはなぜでしょうか? 次のことを試すことで、それをテストできます。

SELECT comment_id FROM comments  ORDER BY comment_id ;

クエリはインデックスに格納されている値のみを必要とするため、インデックスを使用し、ファイルソートは行いません。


MyiSAM で同様の (InnoDB と) 動作が必要な場合は、インデックスを作成して(comment_id, comment_content, comment_author, comment_author_url)からクエリを試すことができます。必要なすべての値がインデックス上で正しい順序で見つかるため、ファイルソートは実行されません。

もちろん、追加のインデックスには、テーブルとほぼ同じディスク容量が必要です。


1 : ファイルソートは常に悪いわけではなく、ファイルがディスクに保存されるという意味でもありません。データのサイズが小さい場合は、メモリ内で実行されます。

于 2012-08-12T10:28:04.220 に答える
10

インデックスからソートを実行できない場合はいつでも、それはファイルソートです。

ここで奇妙なことは、それが主キーであるため(そして主キー列は暗黙的にインデックスが作成されているため)、そのフィールドにインデックスが必要であることですSELECT *。意味のない動作です(私は知っています)が、このようにクエリを書き直すと:

SELECT comment_id, comment_content, comment_author, comment_author_url 
FROM comments  
ORDER BY comment_id

インデックスを正しく使用します。たぶんmysqlのバグかもしれません...

于 2012-08-12T09:12:01.883 に答える