主キー/クラスター化インデックスでの GUID の使用
-
16-09-2019 - |
質問
私は SQL サーバーのパフォーマンスにはかなり精通していますが、クラスタ化された主キーのデフォルトの種類として GUID を使用する必要があるという考えには常に反論しなければなりません。
テーブルの 1 日あたりの挿入量がかなり少ない (1 日あたり 5000 +/- 行) と仮定すると、どのようなパフォーマンスの問題が発生する可能性がありますか?ページ分割はシークのパフォーマンスにどのような影響を及ぼしますか?どのくらいの頻度でインデックスを再作成する必要がありますか (またはデフラグすべきですか)?フィルファクターを (100、90、80 など) に設定する必要がありますか?
1 日あたり 1,000,000 行を挿入するとどうなるでしょうか?
質問ばかりで申し訳ありませんが、PK のデフォルトとして GUID を使用しないためのバックアップを探しています。しかし、私は StackOverflow ユーザー ベースからの圧倒的な知識によって考えが変わることを完全に歓迎します。
解決
あなたがボリュームのいずれかの種類を行っている場合は、GUIDがPKとして悪い非常に悪いですシーケンシャルGUIDはあなたが記述の正確な理由のために、に。 ページの断片化は、:
Average Average
Fragmentation Fragment Fragment Page Average
Type in Percent Count Size Count Space Used
id 4.35 7 16.43 115 99.89
newidguid 98.77 162 1 162 70.90
newsequentualid 4.35 7 16.43 115 99.89
ととしてのGUIDと整数の間、この比較には示しています。
あなたのボリュームが非常に低い場合は、のTest1がページ分割の膨大な量を引き起こし、そして周りのスキャン密度を有していた12の%の挿入が完了した後、私はDBCC SHOWCONTIGを実行したとき。 Test2をテーブルには98%の周りにスキャン密度を有していた。
、しかし、それだけではあまり重要ではありません。
あなただけのインデックス付きの列にGUIDを入れて、本当にグローバルに一意のIDが必要になりますが、高いボリュームを持っている(とシーケンシャルIDを使用することはできません)ない場合ます。
他のヒント
GUID を主キーとして使用する場合の欠点:
- 意味のある順序付けがないということは、インデックス作成によって整数の場合のようにパフォーマンスが向上しないことを意味します。
- GUID のサイズは 16 バイトですが、整数の場合は 2、4、または 8 バイトです。
- 人間にとって非常に覚えにくいため、参照 ID としては役に立ちません。
利点:
- 推測不可能な主キーを許可することで、Web ページのクエリ文字列またはアプリケーションに表示される場合の危険性が低くなります。
- 自動インクリメントまたは ID データ型を提供しないデータベースで役立ちます。
- プラットフォームまたは環境全体で 2 つの異なるデータ ソース間のデータを結合する必要がある場合に便利です。
GUID を使用するかどうかの決定は非常に簡単だと思いましたが、おそらく他の問題に気づいていません。
1 日あたりの挿入数がこれほど少ない場合、ページ分割が重要な要素であるとは思えません。本当の問題は、5,000 が既存の行数とどのように比較されるかということです。これは、分割を延期するための適切な初期フィル ファクターを決定するために必要な主な情報となるためです。
とはいえ、私は個人的に GUID の大ファンではありません。状況によってはうまく機能することは理解していますが、多くの場合、[効率性、使いやすさ、...] の「邪魔」にすぎません。
GUID を使用する必要があるかどうかを判断する際に、次の質問が役立つと思います。
- PK は共有/公開されますか?(すなわち、SQL 内での内部使用を超えて使用されるのでしょうか。アプリケーションはこれらのキーをある程度永続的な方法で必要とするのでしょうか?ユーザーはどういうわけかこれらのキーを見ますか?
- PK を使用して、異なるデータ ソースをマージすることはできますか?
- テーブルには、データ内の列から作成されたプライマリ (おそらく複合) がありますか?このキーのサイズはどれくらいですか
- 主キーはどのようにソートされるのでしょうか?複合の場合、最初の数列は選択的ですか?
クラスタ化インデックスとして(それがシーケンシャルGUIDでない限り)挿入のパフォーマンスを殺すために起こっているGUIDを使用します。物理テーブルレイアウトは、クラスタ化インデックスに従って整列されているので、ランダムなシーケンス順序を持っているGUIDを使用すると、重大なテーブルの断片化が発生します。あなたはPK /クラスタ化インデックスとしてGUIDを使用したい場合は、SQL Serverの中newsequentialid()関数を使用してシーケンシャルGUIDでなければなりません。これは、生成されたGUIDを順次注文されることを保証し、断片化を防ぐことができます。