他の回答で提案されている主キーの順序には同意しません。
理想的なシナリオ(正確なサンプル クエリの場合)は、関連するすべてのレコードを並べて配置することです。これにより、データに対する単一のシークが有効になります。たとえば、クラスター化(d1, s1, time)
された主キーとして使用すると、次のようにデータが保存されます...
d1 | s1 | time
----+----+------
1 | 1 | 1234
1 | 1 | 1235 \
1 | 1 | 1236 SELECT * FROM table WHERE d1 = 1 AND s1 = 1 AND time BETWEEN 1235 AND 1237
1 | 1 | 1237 /
1 | 1 | 1238
1 | 2 | 1234
1 | 2 | 1235
1 | 2 | 1236
1 | 2 | 1237
1 | 2 | 1238
他の人が示唆しているtime
ように、クラスター化インデックスの最初のフィールドとして持っている場合、1 つの連続したブロックですべてのデータを取得することはできません。代わりに、個々の時間値ごとに 1 つのシークを取得します...
time | d1 | s1
------+----+----
1234 | 1 | 1 *Desired Row 1
1234 | 1 | 2
1235 | 1 | 1 *Desired Row 2
1235 | 1 | 2
1236 | 1 | 1 *Desired Row 3
1236 | 1 | 2
1237 | 1 | 1 *Desired Row 4
1237 | 1 | 2
1238 | 1 | 1 *Desired Row 5
1238 | 1 | 2
この構造は、実際には別のクエリに非常に適しています...
SELECT * FROM yourTable WHERE time = 1234 AND d1 = 1 AND s2 BETWEEN 2 AND 3
これは、単一の普遍的に完全なクラスター化インデックスが存在しないことを示しています。では、クラスター化インデックスは 1 つしか持てないため、クラスター化する対象をどのように選択するのでしょうか?
それは、データとクエリによって異なります。クエリごとに、引き出そうとしている連続したデータ ブロックの数を確認する必要があります。これらのブロックの数を最小限に抑えることは、非常に良い考えです。ただし、GROUP BY または ORDER by 句に適合するようにデータの順序を維持することも同様です。JOIN はこれをさらに複雑にします。
クエリの例では、最初に提案したインデックスが実際に最適です。しかし、すべてのクエリに対してではありません。
また、断片化を考慮する必要があります。データはページに保存され、データが挿入される方法を考慮する必要があります (これについて考えるときは、更新を削除と挿入として扱います)。挿入は通常、既存のデータよりも新しい時間値に対して行われる可能性が高いためtime
、クラスター化されたインデックスを最初にすることで、断片化が減少します。
たとえば、各ページには 3 行のデータしか保持できないとします。上で提案された 2 つのインデックスは次のようになります...
d1 | s1 | time time | d1 | s1
----+----+------ ------+----+----
1 | 1 | 1234 \ 1234 | 1 | 1 \
1 | 1 | 1235 Page 1 1234 | 1 | 2 Page 1
1 | 1 | 1236 / 1235 | 1 | 1 /
----+----+------ ------+----+----
1 | 1 | 1237 \ 1235 | 1 | 2 \
1 | 1 | 1238 Page 2 1236 | 1 | 1 Page 2
1 | 2 | 1234 / 1236 | 1 | 2 /
----+----+------ ------+----+----
1 | 2 | 1235 \ 1237 | 1 | 1 \
1 | 2 | 1236 Page 3 1237 | 1 | 2 Page 3
1 | 2 | 1237 / 1238 | 1 | 1 /
----+----+------ ------+----+----
1 | 2 | 1238 -Page 4 1238 | 1 | 2 -Page 4
では、挿入してみd1 = 1, s1 = 1, time = 1239
ます。
d1 | s1 | time time | d1 | s1
----+----+------ ------+----+----
1 | 1 | 1234 \ 1234 | 1 | 1 \
1 | 1 | 1235 Page 1 1234 | 1 | 2 Page 1
1 | 1 | 1236 / 1235 | 1 | 1 /
----+----+------ ------+----+----
1 | 1 | 1237 \ 1235 | 1 | 2 \
1 | 1 | 1238 Page 2 1236 | 1 | 1 Page 2
*1 | 1 | 1239*/ 1236 | 1 | 2 /
----+----+------ ------+----+----
1 | 2 | 1234 -Page 3 1237 | 1 | 1 \
----+----+------ 1237 | 1 | 2 Page 3
1 | 2 | 1235 \ 1238 | 1 | 1 /
1 | 2 | 1236 Page 4 ------+----+----
1 | 2 | 1237 / 1238 | 1 | 2 -Page 4
----+----+------ 1239 | 1 | 1 /
1 | 2 | 1238 -Page 5
左側のバージョンは、新しいページを作成する必要がありました。右側のバージョンは、既存のページを埋め続けただけです。
断片化が発生した場合、多くの場合、断片化を修正できる保守計画があります。多くの場合、これは夜通しのプロセスです。
それはすべて少し複雑ですよね?まあ、このトピックだけの本があります。
問題が発生するまで、通常は断片化についてあまり心配しません。しかし、それは本当に心に留めておく価値のあるものです。