質問

一意のデータのみが uniqueidentifier (Guid) 列であるテーブルがいくつかあります。GUID は非シーケンシャルであるため (クライアント側で生成されるため、 newsequentialid() を使用できません)、テーブルにクラスター化プライマリを与えるのではなく、この ID フィールドに非プライマリ、非クラスター化インデックスを作成しました。鍵。

このアプローチがパフォーマンスにどのような影響を与えるのか疑問に思っています。何人かの人々が、たとえ意味がなくても、クラスター化された主キーとして自動インクリメント (「アイデンティティ」) int をテーブルに持つべきだと提案しているのを見てきました。これは、データベース エンジン自体がその値を迅速に使用できることを意味するからです。ブックマークを使用する代わりに行を検索します。

私のデータベースは多数のサーバー間でマージ レプリケートされているため、レプリケーションで正確に行うには少し面倒なため、identity int 列は避けてきました。

あなたの考えは何ですか?テーブルには主キーが必要ですか?それとも、クラスタ化インデックスを作成する適切な列がない場合は、クラスタ化インデックスがなくても問題ありませんか?

役に立ちましたか?

解決

インデックスを扱うときは、テーブルを何に使用するかを決定する必要があります。主に 1 秒あたり 1000 行を挿入し、クエリを実行しない場合、クラスター化インデックスはパフォーマンスに悪影響を及ぼします。1 秒あたり 1000 件のクエリを実行している場合、インデックスがないとパフォーマンスが非常に低下します。クエリ/インデックスを調整する場合の最善の方法は、SQL Server のクエリ プラン アナライザーと SQL プロファイラーを使用することです。これにより、コストのかかるテーブル スキャンやその他のパフォーマンスの阻害要因がどこで発生しているかがわかります。

GUID と ID の議論に関しては、両方を支持する人がオンラインで見つかります。私は、よほどの理由がない限り、GUID を使用するように常に教えられてきました。Jeff は、GUID を使用する理由について説明した優れた投稿を投稿しています。 https://blog.codinghorror.com/primary-keys-ids-versus-guids/.

開発関連のほとんどのことと同様、パフォーマンスの向上を目指す場合、唯一の正解はありません。それは実際に、何を達成しようとしているのか、そしてソリューションをどのように実装しているのかによって異なります。唯一の本当の答えは、パフォーマンス指標に対してテストを繰り返し、目標を達成していることを確認することです。

編集] @Matt、GUID/IDの議論についてさらに調査した後、この投稿に出会いました。前にも述べたように、真の正解や不正解はありません。それは具体的な実装ニーズによって異なります。ただし、GUID を主キーとして使用する正当な理由は次のとおりです。

たとえば、テーブル内のデータの特定のページが比較的激しい通貨競合にさらされている「ホットスポット」として知られる問題があります。基本的に、テーブル上のトラフィックの大部分 (したがってページレベルのロック) は、テーブルの最後のほうの小さな領域で発生します。IDENTITY は連続番号ジェネレーターであるため、新しいレコードは常にこのホットスポットに送られます。これらの挿入は、追加先のページ (ホットスポット) で排他的ページ ロックを必要とするため、面倒です。これにより、ページ ロック メカニズムのおかげで、テーブルへのすべての挿入が効果的にシリアル化されます。一方、NewID() はホットスポットの影響を受けません。NewID() 関数を使用して生成された値は、挿入の短いバースト (複数行の挿入中など、関数が非常に迅速に呼び出される場合) の場合にのみ連続するため、挿入された行は代わりにテーブルのデータ ページ全体にランダムに広がります。すべての最後に - これにより、インサートからホットスポットが排除されます。

また、インサートはランダムに分散されるため、ページが分割される可能性が大幅に減少します。ページをあちこちに分割するのはそれほど悪いことではありませんが、その効果はすぐに加算されます。IDENTITY を使用すると、ページ フィル ファクターはチューニング メカニズムとしてはほとんど役に立たないため、100% に設定したほうがよいでしょう。行は最後のページ以外のページには挿入されません。NewID() を使用すると、実際にパフォーマンスを実現するツールとして Fill Factor を利用できます。フィル ファクターを、インデックスの再構築間の推定ボリューム増加を概算するレベルに設定し、dbcc reindex を使用してオフピーク時間中に再構築をスケジュールできます。これにより、ページ分割によるパフォーマンスの低下がオフピーク時まで実質的に遅延されます。

もしあなたさえ 考える 問題のテーブルのレプリケーションを有効にする必要がある場合があります。その場合は、PK を uniqueidentifier にして、guid フィールドに ROWGUIDCOL のフラグを設定することもできます。レプリケーションには、この属性を持つ一意の値の guid フィールドが必要で、存在しない場合は追加されます。適切なフィールドが存在する場合は、そこにあるフィールドが使用されます。

PK に GUID を使用するもう 1 つの大きな利点は、値が、によって生成されたすべての値の中でだけでなく、実際に一意であることが保証されるという事実です。 これ サーバー、ただし、によって生成されたすべての値 全て コンピュータ - データベース サーバー、Web サーバー、アプリ サーバー、クライアント マシンなど。現在、ほとんどすべての最新言語に有効な GUID を生成する機能が備わっています。.NET では System.Guid.NewGuid を使用できます。これは、特にキャッシュされたマスター/詳細データセットを扱う場合に非常に便利です。レコードがコミットされる前に、レコードを関連付けるためだけに、クレイジーな一時キースキームを採用する必要はありません。レコードの作成時に、新しいレコードの永続キー値ごとに完全に有効な新しい GUID をオペレーティング システムからフェッチするだけです。

http://forums.asp.net/t/264350.aspx

他のヒント

主キーには次の 3 つの目的があります。

  • 列が一意である必要があることを示します
  • 列が null 以外である必要があることを示します
  • これが行の一意の識別子であるという意図を文書化します。

最初の 2 つは、すでに行ったようにさまざまな方法で指定できます。

3 番目の理由は良いことです。

  • 人間にとって、あなたの意図を簡単に理解できるようになる
  • そのため、テーブルを比較または処理するプログラムは、テーブルの主キーについてデータベースにクエリを実行できます。

主キーは自動インクリメントする数値フィールドである必要はないので、guid 列を主キーとして指定することをお勧めします。

マットが私を少し誘惑したので、飛び込んでみました。

クラスター化インデックスはデフォルトでテーブルの主キーに配置されますが、2 つの概念は別のものであり、別々に考慮する必要があることを理解する必要があります。CIX は、データが NCIX によって格納および参照される方法を示します。一方、PK は、テーブルの論理要件を満たすために各行の一意性を提供します。

CIX のないテーブルは単なるヒープです。PK のないテーブルは、多くの場合「テーブルではない」と見なされます。データベース設計において賢明な決定を下せるように、PK と CIX の両方の概念を別々に理解することが最善です。

ロブ

実際の質問には誰も答えませんでした:PK や CLUSTERED インデックスがないテーブルの利点と欠点は何ですか。私の意見では、より高速な挿入 (特に増分一括挿入) を最適化すると、空ではないテーブルにデータを一括ロードする場合)、次のようなテーブル:シンプルなリカバリ モデルを使用したデータベースで、クラスター化インデックス、制約、外部キー、デフォルト、主キーを使用しないのが最適です。ここで、(テーブル全体をスキャンするのではなく) このテーブルにクエリを実行する必要がある場合は、必要に応じて非クラスター化非一意インデックスを追加することもできますが、そのインデックスは最小限にとどめてください。

私も、実際に使用しない場合でも、自動インクリメントする int を使用するとパフォーマンスが向上すると聞いたことがあります。

主キーは自動インクリメントフィールドである必要はありません。多くの場合、これは単にテーブル構造が複雑になることを意味します。

代わりに、主キーは、タプルを一意に識別する属性の最小限のコレクションである必要があります (ほとんどの DBMS では複合主キーが許可されることに注意してください)。

技術的に言えば、タプル内の他のすべてのフィールドが完全に機能的に依存するフィールドである必要があります。(そうでない場合は、正規化する必要があるかもしれません)。

実際には、パフォーマンスの問題により、テーブルを結合したり、増加するフィールドを使用したりする必要があるかもしれませんが、時期尚早な最適化は悪であるということを思い出したような気がします...

レプリケーションを行っているので、正しいアイデンティティは避けるべきです。newsequentialid は使用できないため、GUID を主キーにしますが、非クラスター化します。それがあなたの最良のコースだと思います。PK にせずに一意のインデックスを付けると、遅かれ早かれ、システムを保守する人が FK の関係を適切に理解できなくなり、バグが発生する可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top