InnoDBでは、セカンダリインデックスには、テーブルのプライマリキー列が内部的に含まれています。したがって、インデックス name on column(name)は暗黙的にon column(name、id)です。
これは、EXPLAINがカテゴリテーブルへのアクセスを「インデックススキャン」として表示することを意味します(これはタイプに表示されます) 「インデックス」としての列)。インデックスをスキャンすることで、2番目のテーブルitemの行を検索するために使用するid列にもアクセスできます。
次に、実際には(category_id、id)である(category_id)のアイテムインデックスも利用し、インデックスを読み取るだけで、選択リストのitem.idをフェッチできます。表を読む必要はまったくありません(これは Extraに示されています 「インデックスの使用」としての列)。
MyISAMは、この方法で主キーと二次キーを格納しないため、同じ最適化を取得できません。カテゴリテーブルへのアクセスは、テーブルスキャンを意味する「ALL」タイプです。
MyISAMテーブルアイテムへのアクセスは、(category_id)のインデックスを使用して行を検索するため、「ref」になると思います。ただし、テーブルに行が非常に少ない場合、またはANALYZE TABLE item
を実行していない場合、オプティマイザは歪んだ結果を取得する可能性があります。 インデックスを作成してから。
更新を再確認してください:
オプティマイザーはテーブルスキャンよりもインデックススキャンを優先するように見えるため、InnoDBでインデックススキャンを実行する機会があり、カテゴリテーブルが最初に配置されます。オプティマイザは、クエリで指定した順序でテーブルを使用する代わりに、テーブルを並べ替えることを決定します。
MyISAMテーブルには、1つのテーブルがあります。最初にアクセスすることを選択したテーブルをスキャンしますが、カテゴリテーブルを2番目に配置することで、アイテムのセカンダリインデックスではなくカテゴリのPRIMARYキーインデックスに結合します。オプティマイザーは、一意のキーまたは主キー(「eq_ref」と入力)よりもルックアップを優先します。