8

外部キーのインデックスと、それらの外部キーを含むクラスター化インデックスを持つ多くのテーブルがあります。たとえば、次のようなテーブルがあります。

TABLE: Item
------------------------
id       PRIMARY KEY
owner    FOREIGN KEY
status

... many more columns

MySQL は主キーと外部キーのインデックスを生成しますが、クエリのパフォーマンスを向上させたい場合があるため、クラスター化インデックスまたはカバリング インデックスを作成します。これにより、列が重複するインデックスが作成されます。

INDEXES ON: Item
------------------------
idx_owner (owner)
idx_owner_status (owner, status)

を削除した場合idx_owner、通常使用する将来のクエリは、インデックスの最初の列として使用するidx_ownerだけです。idx_owner_statusowner

持ち歩く価値はありidx_ownerますか?idx_owner_statusMySQL がインデックスの一部しか使用しない場合でも、使用する追加の I/O オーバーヘッドはありますか?

編集:私は本当にInnoDBがインデックスに関してどのように動作するかにのみ興味があります。

4

1 に答える 1

7

簡単な回答 短いインデックスを削除します。

ロングアンサー 考慮すべき事項:

もうやめろ:

  • それぞれINDEXがディスク上に存在する個別の BTree であるため、スペースが必要です。
  • 新しい行またはインデックス付きの列を変更すると、それぞれINDEXが (遅かれ早かれ) 更新されます。これには、「変更バッファー」のために CPU と I/O および buffer_pool スペースが必要です。INSERTUPDATE
  • 短いインデックスの機能的な使用 (パフォーマンスとは対照的に) は、長いインデックスで実行できます。

落とさないでください:

  • 長いインデックスは、短いインデックスよりもかさばります。そのため、キャッシュ可能性が低くなります。そのため (極端な状況では) 短い方の代わりにかさばる方を使用すると、より多くの I/O が発生する可能性があります。これを悪化させるケース: INDEX(int, varchar255).

最後の項目が他の項目を実際にオーバーライドすることは非常にまれです。

ボーナス

「カバリング」インデックスは、 に記載されているすべての列を含むインデックスですSELECT。例えば:

SELECT status FROM tbl WHERE owner = 123;

これはの BTreeのみに触れるためINDEX(owner, status)

SELECT status, foo FROM tbl WHERE owner = 123;

そのクエリをより高速にする必要がある場合は、両方のインデックスをINDEX(owner, status, foo).

セカンダリ キーの PK

もう 1 つ情報があります... InnoDB では、 の列がPRIMARY KEYすべてのセカンダリ キーに暗黙的に追加されます。つまり、3 つの例は実際には

INDEX(owner, id)
INDEX(owner, status, id)
INDEX(owner, status, foo, id)

複合インデックスインデックス クックブックに関する私のブログでの詳細な議論

于 2015-09-06T00:50:00.887 に答える