2012-03-02 11 views
10

私は、おそらく数百万行のサイズになるMYSQLデータベースのテーブルにコンポジットインデックスを追加する方法を検討しています。コンポジットは、2つのvarcharカラムと3つのintカラムで構成されます。私の質問はタイトルに記載されています:この複合インデックスを作成する最適な順序はありますか?たとえば、int行のうちの1つは6つの可能な値しか持たないため、その列がインデックス定義の前面に近いほうがよいでしょうか?同様に、varcharカラムの1つは、おそらくインデックス定義の前または後ろにあるはずの数百万の異なる値を持つでしょうか?MYSQLコンポジットインデックスを注文する最適な方法はありますか?

+0

範囲ではなく、WHERE句に定数を選択していますか? –

+0

Marcus、私はおそらく、このテーブルへのクエリの大多数の定数を選択します。 – chicagoCrazy

答えて

16

大まかには、複数列インデックスでは、インデックス内で基数が最も高い列、つまり最も重複する値の列が最初に来るようにします。

より正確にするには、できるだけ一致の少ない列を最初に検索し、できるだけ結果セットを絞り込むことができますが、一般的には最高の基数と同じです。

したがって、例では、6つの異なる値を持つ列の前に、数百万の異なる値を持つ列が索引に存在することが必要です。

数百万の値から1つの行だけを選択していると仮定すると、より多くの行をより早く除去することができます。

類似のカーディナリティの2つの列を考えるときは、小さいものを最初に(INTEGER列をVARCHAR列の前に)配置します。これは、MySQLがそれらを比較してより高速に反復できるからです。

範囲(たとえばWHERE datecol > NOW())を使用して選択する場合は、範囲の列が最も右側に、列が単一の定数(たとえば、WHERE id = 1)を左側に置きます。これは、インデックスが最初の範囲値のポイントまでの検索と並べ替えにしか使用できないためです。

+4

カーディナリティは必ずしも適切な基準ではありません。インデックス内の最初の列には2つの値しかなく、後続の列にはカーディナリティが高くなります。これは、インデックスが常に2つの値のうちの1つだけを使用する特定の検索用に設計されており、その値が結果セットを95%減らすためです。正しい質問は、どの列が結果セットを最も減らすかであり、カーディナリティーはほんの便利なルールです。 –

+1

@カイ、あなたのコメントは私を混乱させる。たぶん具体例を挙げることができます。 –

+0

@MarcusAdams私はカイのことを理解している、私はそれがここでかなりうまく説明されていると思う:http://www.percona.com/blog/2009/06/05/a-rule-of-thumb-for-choosing-column index-in-indexes/ –

関連する問題