1

次の形式のファクト テーブルを考えてみましょう。

CREATE TABLE Fact1
(
    Dim1 int NOT NULL,
    Dim2 int NOT NULL,
    Dim3 int NOT NULL,
    Data1 int NOT NULL,
    Data2 int NOT NULL
    ...
)

Fact1各次元に 1 つの列インデックスがあります。Dim1時間の範囲までの粒度を持つ時間ディメンションであると想定されます (たとえば、2011 年 3 月 12 日の午後 2 時から午後 6 時の間)。Dim1 内の列をカバーするものとして含めるDim2と便利でしょうか? Dim3または同様にそれらのいずれかで?

より一般的には、他のディメンション テーブルの FK 列を特定のディメンションのインデックスのカバー列として含めると便利でしょうか?

注: ファクト テーブルについては、特定のファクトを一意に識別する必要はないと想定しています。したがって、主キーまたは代理キーがありません。(Dim1, Dim2, Dim3) が常に一意のタプルであることによって、一意性が保証されます。

4

1 に答える 1

4

より一般的な質問に答えようと思います。「特定のディメンションのインデックスのカバー列として、他のディメンション テーブルの FK 列を含めると便利でしょうか?」

はい。COUNT() などを実行するクエリが多数ある場合、カバリング インデックスにより小さなデータ セットをスキャンできる場合は、それらの他のディメンションを追加することが重要な場合があります。

SELECT Dim1, Dim2, count(*)
from Fact1
group by Dim1, Dim2

Dim1 のみまたは Dim2 のみのインデックスでは、このカウントを行うために FTS を実行する必要があります。これはまったく問題ないかもしれません。フル スキャンが必ずしも悪いわけではありません。ただし、これらの種類のクエリを高速化したい場合 (たとえば、ファクト テーブルが非常に広い場合)、Dim1、Dim2 に B ツリー インデックスを追加すると、DBMS はインデックスに移動してカウントする必要がなくなります。カウントするテーブルに。それでもインデックスのフル スキャンが実行されることに注意してください。これは、フル テーブル スキャンよりもわずかに高速である可能性があります。

一般に、とにかくインデックスのすべての行をスキャンしているため、それほどパフォーマンスが向上するとは思えません。また、インデックスがテーブルよりも大幅に小さい場合を除き、おそらく大きな改善は見られません。

これはファクト テーブルであるため、ディメンションのインデックスをカバーすることが役立つ唯一のクエリは、ディメンション自体のみがクエリされる場合です。ファクトを使用するものはすべて、インデックス スキャンが必要です。次に、テーブル内で実際のデータを検索します。

おそらく、キー (および結合) を使用するクエリの Dims に B ツリー インデックスを作成し、システムがしばらく実行され、一般的なクエリが特定されたときに、必要に応じて追加の B ツリー インデックスを追加します。

このような「カバリング」インデックスがクエリの高速化に役立つと考えられるもう 1 つのケースは、特定のディメンションの組み合わせに焦点を当てたクエリがあり、それらの特定の行のみが必要な場合です。

SELECT Dim1, Dim2, Data1, Data2
  FROM Fact1 
 WHERE Dim1 = @A and Dim2 = @B;

WHERE 句のすべての項目のインデックスをスキャンしてからファクト データを取得するため、Dim1, Dim2単に ではなくに B ツリー インデックスを設定すると、パフォーマンスがわずかに向上することがあります。Dim1

于 2012-06-15T19:08:10.707 に答える