33

SQL Server 2005 (おそらく近い将来 SQL Server 2008) を使用して Web サイト用の新しいデータベースを作成しています。アプリケーション開発者として、リレーションシップに使用されるテーブルの ID フィールドにinteger(またはなど)を使用する多くのデータベースを見てきました。しかし最近、ID フィールドに( ) をbigint使用するデータベースも見ました。unique identifierGUID

私の質問は、一方が他方よりも優れているかどうかです。integerフィールドのクエリや結合などは高速化されますか?

更新:明確にするために、これはテーブルの主キー用です。

4

6 に答える 6

53

GUID はランダム性が高いため、クラスター化されたキーとして問題があります。この問題は、Technet Magazine の最後の Q&A コラムで Paul Randal によって取り上げられました。クラスタ化されたインデックス キーとして GUID を使用したいのですが、インデックスのパフォーマンスの問題につながる可能性があると他の人が主張しています。これは本当ですか? もしそうなら、その理由を説明していただけますか?

ここでの説明は、特にクラスター化インデックスに関するものであることに注意してください。列を「ID」として使用したいと言っていますが、クラスター化されたキーまたは単に主キーとして意味するかどうかは不明です。通常、この 2 つは重複するため、クラスター化インデックスとして使用することを前提としています。それが不適切な選択である理由は、上記の記事へのリンクで説明されています。

クラスター化されていないインデックスの場合、GUID にはまだいくつかの問題がありますが、テーブルの一番左のクラスター化されたキーの場合ほど大きくはありません。繰り返しになりますが、GUID のランダム性により、ページの分割と断片化が発生します。これは、クラスター化されていないインデックス レベルでのみ発生します (はるかに小さな問題です)。

int (4 バイト) と比較して、GUID のサイズ (16 バイト) に基づいて GUID の使用を非難し、それらを使用すると恐ろしいパフォーマンスの破滅を約束する多くの都市伝説があります。これは少し誇張されています。適切に設計されたデータ モデルでは、サイズ 16 のキーでも非常にパフォーマンスの高いキーになる可能性があります。int の 4 倍の大きさになると、インデックス内の非リーフ ページの密度が低くなることは事実ですが、これは大部分のテーブルにとって実際の問題ではありません。b-tree 構造は自然にバランスの取れたツリーであり、深さツリー トラバーサルが問題になることはめったにないため、INT キーではなく GUID キーに基づいて値を検索することは、パフォーマンスが似ています。リーフ ページ トラバーサル (つまり、テーブル スキャン) は、非リーフ ページを調べません。レコード自体は、導入された余分な 12 バイトよりも大幅に大きいため、通常、ページ サイズに対する GUID サイズの影響は非常に小さくなります。 GUIDによって。したがって、私は「16 バイト対 4 バイト」に基づいて、かなり大きな塩の粒を付けて、聞いたアドバイスを受け入れます。個々のケースを分析し、サイズの影響が実際に違いを生むかどうかを判断します:テーブル内の他の列の数 (つまり、GUID サイズがリーフ ページに与える影響) と、それを使用している参照の数 (つまり.より大きな外部キーを格納する必要があるという事実のために、他のテーブルの数が増加します)。

GUID は最近多くの悪い報道を受けており、中には値しないものもあるため、GUID のその場しのぎの防御として、これらすべての詳細を呼び出しています。それらにはメリットがあり、あらゆる分散システムに不可欠です (レプリケーションや同期フレームワークなどを介したデータ移動について話している瞬間)。GUID の評判の悪さに基づいて、適切な検討なしに回避されたときに、悪い決定が行われるのを見てきました。ただし、GUID をクラスター化されたキーとして使用する必要がある場合は、ランダム性の問題に対処する必要があります。可能な場合は連続した GUID を使用してください

そして最後に、あなたの質問に答えるために: GUID を使用する特別な理由がない場合は、INT を使用してください。

于 2009-07-20T04:44:35.960 に答える
8

GUID はより多くのスペースを占有し、int よりも遅くなります - newsequentialid() 関数を使用したとしても。レプリケーションを行うか、同期フレームワークを使用する場合は、ほぼ GUID を使用する必要があります。

于 2009-07-20T04:11:21.380 に答える
6

INT は 4 バイト、BIGINT は 8 バイト、GUIDS は 16 バイトです。データを表現するために必要なスペースが増えるほど、それを処理するためにより多くのリソース (ディスクスペース、メモリなど) が必要になります。したがって、(a) 遅くなりますが、(b) これはおそらくボリュームが問題になる場合にのみ問題になります (数百万の行、または非常に短い時間で数千のトランザクション。)

GUID の利点は、(ほぼ) グローバルに一意であることです。適切なアルゴリズムを使用して GUID を生成すると (SQL Server xxxx は適切なアルゴリズムを使用します)、GUID を生成するコンピューターの数や頻度に関係なく、2 つの GUID は同じにはなりません。(これは72年間の使用では当てはまりません。詳細は忘れました。)

複数のサーバーで生成された一意の識別子が必要な場合は、GUID が役立つ場合があります。mondo パフォーマンスが必要で、20 億未満の値が必要な場合は、おそらく int で問題ありません。最後に、そしておそらく最も重要なこととして、データに自然キーがある場合は、それらに固執し、代理値を忘れてください。

于 2009-07-20T04:19:55.480 に答える
5

肯定的な場合は、絶対に一意の ID、次に GUID が必要です。つまり、マージ、同期、複製を行う場合は、おそらく GUID を使用する必要があります。

堅牢性の低いものについては、テーブルがどれだけ大きくなるかに応じて、int で十分です。

ほとんどの場合、適切な答えは、場合によって異なります。

于 2009-07-20T04:13:34.153 に答える
3

主キーとしてではなく、レプリケーションなどに使用してください。

キンバリー・L・トリップの記事

  • 反対: スペース、厳密には単調ではない、ページ分割、ブックマーク/RID など
  • 用: ええと...
于 2009-07-20T04:28:52.983 に答える
2

JBrooksに完全に同意しました。テーブルが大きく、特に派生テーブルで JOINS で選択を使用する場合、GUID を使用するとパフォーマンスが大幅に低下する可能性があります。

于 2009-07-20T04:17:59.697 に答える