41

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

このアプローチがパフォーマンスにどのような影響を与えるのか疑問に思っています。データベースエンジン自体がその値を使用してすばやくブックマークを使用する代わりに行を検索します。

私のデータベースは多数のサーバー間でマージ レプリケートされているため、ID の int 列を避けています。

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

4

7 に答える 7

33

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

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

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

[編集] @Matt、GUID/ID の議論についてさらに調査を行った後、この投稿に出会いました。前述したように、正解も不正解もありません。それは、特定の実装ニーズによって異なります。しかし、GUID を主キーとして使用する正当な理由がいくつかあります。

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

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

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

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

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

于 2008-08-08T03:04:29.047 に答える
7

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

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

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

3 番目の理由は適切です。

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

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

于 2008-08-08T03:04:55.037 に答える
7

マットが私を少しおびき寄せたので、ただ飛び込みます。

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

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

ロブ

于 2009-08-05T04:51:00.373 に答える
3

誰も実際の質問に答えませんでした: PK もクラスター化されたインデックスもないテーブルのプラス/マイナスは何ですか。私の意見では、挿入を高速化するために最適化する場合 (特に、空でないテーブルにデータを一括ロードする場合などの増分一括挿入)、そのようなテーブル: クラスター化インデックスなし、制約なし、外部キーなし、デフォルトなし、および単純復旧モデルのデータベースでは、主キーなしが最適です。ここで、(全体をスキャンするのではなく) このテーブルにクエリを実行する場合は、必要に応じてクラスター化されていない非一意のインデックスを追加する必要がありますが、それらは最小限に抑えます。

于 2010-03-19T18:17:12.213 に答える
0

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

于 2008-08-08T03:00:36.810 に答える
0

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

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

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

実際には、パフォーマンスの問題は、テーブルをマージして増分フィールドを使用することを意味する場合がありますが、時期尚早の最適化が悪であることについて何か思い出したようです...

于 2008-08-08T06:25:50.030 に答える
0

レプリケーションを行っているため、正しい ID は避けなければなりません。GUID を主キーにしますが、新しいシーケンシャル ID を使用できないため、非クラスター化します。それはあなたの最善の策だと思います。PK にせずに独自のインデックスを付けると、遅かれ早かれシステムを保守する人が FK の関係を正しく理解できずにバグが発生する可能性があります。

于 2010-11-03T18:20:12.173 に答える