ここから本文です

DateTime型の列にインデックスを付けるのは邪道?

thu********さん

2010/6/1100:15:32

DateTime型の列にインデックスを付けるのは邪道?

約100件/日のペースでレコードがINSERTされていくテーブルがあります。そのテーブルにDateTime型の列(秒のオーダーまで記録。簡単に言えばタイムスタンプ)があったとして、そのDateTime型の列にインデックスを付けるのは邪道でしょうか?

・そのDateTime型の列に、値の重複はほとんどありません。また、列は必須入力です。
・タイムスタンプなので、INSERTするレコードはインデックス的には常に末尾近くということになります。
・5年分ほど溜めていきます。6年目になったら、1年目のレコードは削除します。以降、繰り返し。
・DBMSによらない、一般論です。(ちなみに、実際はOracle8iを使っています。)


※「実際問題として、どうか?」が知りたいので、代替案などの‘そもそも論’【のみ】のご回答は、書いてくださる方の時間と労力がもったいないのでご遠慮願います。(問題点をご指摘された上での代替案は大歓迎です!)

補足一般的に、文字列に対してならハッシュ値が生成されてインデックスがまんべんなく構築されていくものと理解しておりますが、DateTime 型のようにフィールドサイズが固定されている場合、もしかしたらハッシュ処理されずにそのままの値でインデックス管理されるのでは?だとしたら、常に最後尾近くにインデックスが追加されるような運用だと、どのような現象が発生するのか?が気になったのが質問の背景です。

閲覧数:
9,471
回答数:
1
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

jhotqyさん

編集あり2010/6/1613:22:19

何を思って「邪道でかも」と思ったのか分かりませんが、必要であるなら邪道ではありません。

「そもそも論はご遠慮」とかかれていますが、そもそも、何かの必要性がある場合にインデックスをつけるので、必要性があるなら邪道ではないと思います。(例えば、検索の時のキーになるや、結合のカラムとなる(秒まで入るならこれは無さそうですが・・・)など)

インデックスの必要性がないカラムにインデックスをつけるのは、データ型に限らず邪道です。

インデックスをつけることによる弊害はご存知ですか?(例えば、InsertやUpdateの速度が落ちるとか、B-Treeインデックスの場合は、インデックスの偏りが考えられるなら、メンテナンスが必要など)
一般論として、このあたりの利点と不利な点を比べ、必要であるかを考えるのが良いかと思います。

ちなみに、当社のシステムでは同じような秒まで保存する列にインデックスをつけて運用しているテーブルもあります。

追加
>一般的に、文字列に対してならハッシュ値が生成されてインデックスがまんべんなく構築されていくものと理解しておりますが
残念ながら、この部分が誤解されておられます。
一般的にインデックスは、列の値そのままで作られます。文字列型だろうが数値型・DateTime型だろうが同じです。
ですので、その列に入っているデータにより偏りも出来ますし、Insert・Updateにより効率よいインデックスにならないこともあります。
ハッシュ値のようなものを使用していない証拠としては、もしハッシュ値の様なものを使用していた場合、前方一致検索や範囲検索・Order Byの並び替えにはインデックスが使用できないことになってしまいます。(インデックスが等価評価による絞込みにしか使えないことになります。)もちろんそのようなことはありませんので、違うことが分かります。もちろん、ハッシュ値を保存するインデックスを作れるDBMSもありますので、一概には言えませんが、その場合は使用方法が限定されることになります。

インデックスが偏ることは、DateTime型でなくても起こることがあります。DateTime型も同じですが、シリアル値を保存するような目的の列です。
例えば、伝票番号を保存する列ですが、これが数値型だった場合、当然ですが、小さな値から順に使われることが多いと思います。つまり、時間が経てばインデックスは偏りが出てしまうため、この偏りを平準化することをしないと効率的にインデックスが使えないことになります。(文字列型でも同じことが言えますね)
DBMSによっては偏りを自動で平準化するような昨日が付いているものもあるかもしれませんが、Oracleの場合は、運用のメンテナンスとして、インデックスの再作成などにより、インデックスの偏りを平準化する必要があります。

ちなみに、インデックスの種類によっては、偏りが出ないものがあります。Oracleではビットマップ索引がそうです。ただしこれは、一般的な列に使用するものではなく、カーディナリティ(選択性)が低い(入るデータの種類が少ない。例えば性別。男女の2種類しか入らない)ような列にだけ使用すべきインデックスです。

当社のシステムで秒まで保存している列のことを言いましたが、これは作業日時を保存する列です。これは、作業日次ごとで集計を取る必要があるため、インデックスをつけています。また、インデックスのメンテナンスは、日次バッチ処理の中で、毎日再作成処理を入れています。これにより、インデックスの効率的な利用が出来るよう、気をつけています。(弊害として、データのファイルの内のデータの断片化が起こっていると思います。)

質問した人からのコメント

2010/6/16 13:39:11

成功 丁寧に解説していただきましてありがとうございます!ずーっと抱えていたモヤモヤが晴れました!

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる