#06 インデックス1つあたりのフィールド数を考える

結論
全般的には複数フィールドに対して1つのインデックスを設ける方がよい。特にインデックスの重複が少ない場合のレコード更新や削除ではその効果が高い。しかしレコードの選択では、インデックスの重複が少ない場合や複数のフィールドに対してWHERE条件を指定するような場合はフィールド個々にインデックスを設けた方がよい可能性もある。

一般的にインデックスは、検索などでのWHERE条件やSORT指定するフィールドに対して設定すると思います。そしてそれらのフィールドが複数ある場合にはインデックスの付け方として2つの方法が考えられます。1つはフィールドごとにその数と同じインデックスを設ける方法、もう一つは複数のフィールド全体に対して1つのインデックスを設ける方法です。

     

インデックスを付けるべきフィールドが複数ある場合、それらのデータ内容が一意なものであれば主キーになり得ます。主キーとするには「それら複数のフィールド全体をまとめてPrimaryKey」とする後者の方法しか採れないので迷うことはないかもしれませんが、そうでない場合は実際どちらがいいのか気になるところです。そこでここでは両者の方法について比較を行ってみました。  

テストの内容としては、あるテーブル内の5つのフィールドに対して、重複ありのインデックスを個々に設定した場合と、1つのインデックスにまとめた場合とで、それぞれ5万件のレコード追加と一部のレコードの読み込み、全レコードの更新、さらに全レコードの削除を行いその処理時間を測定・比較します。さらにインデックスの内容が全レコードとも同じ(重複する)場合と、完全に一意(重複しない)である場合との比較も行います。また、レコードの読み込みではインデックスの設定されているフィールドのうち1つに対してWHERE条件を付けて5千件のレコードを抽出するようにしますが、最後に複数のインデックスフィールドに対してANDでWHERE条件を付けて5千件のレコードを抽出する時間も測定してみます。(テストに用いたコードは#04・#05と類似しているため割愛します)

テスト結果はつぎのようなものになりました。  なお時間の単位は"秒"です。 またカッコで示してある%表示は、フィールド個々にインデックスを設定した場合の時間値に対する比率を表しています。


インデックス 追加 選択 更新 削除
すべてのレコードのインデックスフィールドに同じ値をセット フィールド個々 132.2 7.6 156.2 68.0
まとめて1つのインデックス 103.7
(78%)
5.9
(78%)
115.2
(74%)
55.5
(82%)
すべてのレコードのインデックスフィールドに異なる値をセット フィールド個々 151.4 6.7 226.5 122.6
まとめて1つのインデックス 116.0
(77%)
6.5
(97%)
125.0
(55%)
53.5
(44%)
複数のWhere句を指定してレコード選択(ただし抽出されるレコード数は同じ) フィールド個々 -- 18.4 -- --
まとめて1つのインデックス -- 18.5 -- --

結果から、明らかに複数フィールドに対して1つのインデックスを付けた方がよいことが分かります。特にインデックス内容の重複が少ない場合のレコード更新や削除ではその効果が高くなっています。 しかし注意すべき点もあります。レコードを選択する場合に、インデックス内容の重複が多い時にはインデックスを1つにすることによって時間が78%に短縮されたのに対して、重複が少ない時には97%にしかなっていません。また、複数のインデックスフィールドに対してWHERE条件を指定するような場合には逆にほんの少し多くなっています。このことから、「インデックスの重複が少ない場合や複数のフィールドに対してWHERE条件を指定するような場合にはフィールド個々にインデックスを設けた方がよい可能性もある。」と言えそうです。

| Index | Prev | Next |

 

Copyright © T'sWare All rights reserved