web-dev-qa-db-ja.com

タイムスタンプベースのインデックス

いくつかのログ情報を含む大きなデータベース(200GB +)があります。 SELECTクエリとストアドプロシージャを高速化したいと思います。 GeneratedOnUtcdatetime列を持つテーブルがあり、その上に非クラスター化インデックスがあります。

クラスタ化インデックスに変更することを考えています。

の理由:

  • 大量のデータ(約4,000万行)

  • 列が複数のWhere句で使用されています(between、_>_、_<_)

  • 列はROW_NUMBER() OVER (ORDER BY d.GeneratedOnUtc asc) AS Rowクエリで使用されます

反対の理由:

  • 大量の挿入(1日あたり約60k)は、Bツリーの再構築を頻繁に行う可能性があります。
7
Alex Zhukovskiy

テーブルをヒープからクラスタ化インデックスを持つように変更すると、両方のクエリのパフォーマンスが向上し、おそらく挿入のパフォーマンスも向上するはずです。一般的に言えば、クラスター化インデックスは狭く、一意で、常に増加している必要があります。一意であるとは保証できない日時を使用するのは理想的ではありません。8バイトであり、一意ではないため、SQLは4バイトの一意識別子を一意でない行に追加します。クラスター化インデックスとしてintを含むID列を使用する方がよい場合があります。それは、とにかく「row_number」クエリが実際に実行するもの(常に増加する一意の番号)であるため、特に、非クラスター化インデックスの数(クラスター化は非クラスター化によって行ポインターとして使用されるため、サイズが追加されるため)。 40億の利用可能なint値により、数十年の成長が可能になります。

データベースのテスト用コピーを作成してから、datetime値のクラスター化インデックスを使用してテストし、新しいID列のクラスター化インデックス(およびdatetimeの非クラスター化インデックス)を使用したテストとは対照的です。クエリの負荷でどちらが優れているかを確認します。どちらのシナリオも、ヒープを上回ります。

4
ubergeek