2009-07-23 16 views
4

これまで、私はC# "Guid = Guid.NewGuid();を使用していました。メソッドを使用して、SQLへのLinqを使用して、自分のSQL Serverデータベーステーブルの一部にIDフィールドとして格納できる一意のIDを生成します。 私は、インデックス付けの理由から、GUIDを使用することは悪い考えであり、代わりに自動インクリメントのLongを使用する必要があることを知っています。私のデータベーストランザクションを高速化することはできますか?もしそうなら、Long型の一意のIDを生成するにはどうすればいいですか?SQL Server - Guid VS. Long

よろしく、

+0

"私はインデックスの理由から、GUIDを使用することは悪い考えであることを知らされました" - あなたが持っている場合は IDフィールドのクラスタード・インデックスでは、GUIDは挿入のパフォーマンスを低下させます。 SQL Serverは、クラスタ化インデックスに基づいてテーブルを格納します。新しいGUIDが非シーケンシャルなので、新しい行を挿入すると、最後ではなくテーブルの中央に挿入する必要があり、多くのIOが発生します。クラスタ化されたインデックスの列型である限り、この問題は回避されます。 – adrianbanks

+1

追加するだけです - GUIDがプライマリキーの場合は、デフォルトでGUIDがクラスタ化されます。これはクラスタ化されていない可能性がありますが、手動介入が必要です –

+0

http://sqlblogcasts.com/blogs/martinbell/archive/2009/ 05/25/GUID-Fragmentation-in-SQL-Server.aspx - およびトピックに関する多くのコンテンツを含むポッドキャストについては、http://www.dotnetrocks.com/default.aspx?showNum=455を参照してください。 –

答えて

8

を見ている参照してくださいので、どちらかのテーブルを作成したり、テーブルを変更を使用して

それはあなたがそれらをどのように使っているかにかかっています。

複数のデータベースで動作する識別子が必要な場合は、GUIDが必要です。 Long(各データベースに異なるシード/インクリメントを手動で割り当てる)にはいくつかのトリックがありますが、これらはうまく拡張できません。

インデックスがクラスタリングされている場合(デフォルトではプライマリキーがクラスタ化されていますが、これはテーブルに対して変更できます)、インデックスのパフォーマンスは大幅に向上します。すべてのインサート。

ただし、並行挿入が関係する限り、Long(ID)列の方が処理速度が遅くなります.ID列の生成には、次の連続番号を取得するための一連の排他ロックが必要です。多くのユーザーが常に多くの行を挿入している環境では、これはパフォーマンスの低下につながります。この状況でのGUID生成は高速です。

GUIDは、記憶域の2倍の領域(8バイト対16)を占有します。しかし、8バイトが1つのリーフに収まるレコードの数と、平均要求の間にディスクから引き出されるリーフの数に顕著な差がある場合は、行の全体的なサイズに依存します。

+2

あなたのクラスタリングキーとしてGUIDを使用すると、各値と各クラスタ化されていないインデックスの各エントリにその値(BIGINTの2倍の大きさ)が追加されます。ディスクだけでなくSQL ServerのRAMでもある –

3

長い(SQL Serverの中で大きなint型)8バイトで、GUIDは、16バイトであるので、あなたはバイトのSQL Serverの数を半減しているルックアップを行う際に比較することがあります。

longを生成するには、データベースにフィールドを作成するときにIDENTITY(1,1)を使用します。

Field_NAME BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1) 

+1

L2Sを使用してデータベースに新しいレコードを送信すると、PKは残されたままになります。 L2Sによって送信されますので、提出後にレコードオブジェクトから検索することができます。そうしなければならない場合は、それを行う必要があります。 – Lazarus

+0

SQL Serverのデザインビューを使用してこれを行う方法はありますか?私のSQLスクリプトコードはあまりにもいいです........ – Goober

+0

ありますが、私はそれを行う方法を知らない。申し訳ありません:( – kemiller2002

1

あなたは一日中GUIDまたは身元を討議することができます。私は、IDを使ってユニークな値を生成するデータベースを好む。複数のデータベースからデータをマージする場合は、別の列を追加して(ソースデータベースを識別し、おそらくtinyintまたはsmallint)、複合主キーを作成します。

あなたが発生します予想されるキーの数に基づいて、右のデータ型を選択してください、アイデンティティで行く場合:

bigint - 8 Bytes - max positive value: 9,223,372,036,854,775,807 
int - 4 Bytes - max positive value:    2,147,483,647 

注「期待キーの数は」数とは異なっています行。主に行を追加して保持すると、INTが20億個以上のユニークキーで十分であることがわかります。私はあなたのテーブルがそれほど大きくないと確信しています。ただし、行の追加と削除を続ける大量の表がある場合は、行数は少なくなる可能性がありますが、キーをすばやく通過します。あなたは、INTsの20億の鍵を通過するためにどのようにログが取られるかを見るためにいくつかの計算を行うべきです。すぐに使用しない場合は、INTを使用してください。それ以外の場合は、キーサイズを2倍にしてBIGINTを使用してください。

3

"インデックスの女王" - Kim Tripp - 基本的に彼女のインデックスブログの記事でそれをすべて言う:

は基本的に、彼女のベストプラクティスであります:最適なクラスタリング・キーは次のようになります。

  • ユニーク
  • 小さな
  • 安定(変更はありません)
  • 増え続ける

GUIDさんは "小さい" と "増え続ける" を侵害するので、最適ではありません。

PLUS:すべてのクラスタ化キーは、クラスタ化されていない単一のインデックス(データベース内のレコードを実際に検索するルックアップ)の各エントリに1つずつ追加されるため、可能な限り(INT = 4バイト対GUID = 16バイト)。だけでも、スペースワイズ - あなたが行と複数の非クラスタ化インデックスの数百万を持っている場合は、GUIDの上にINTまたはBIGINTを選択することが大きな違いを生むことができます。

マーク

+2

スケールについて心配している場合は、GUIDを選択しないでください。小さなデータベースでは速度やスケールの観点から大きな違いはありませんが、100ミリオン+ローテーブルGUIDはパフォーマンス上の悪夢です...上記のKim Trippの記事を読むと、それは大きな決定であり、3ヵ月の技術的負債 – BoomTownTech

1

複数のデータベースへのインポート/エクスポートを検討する必要がある場合は、guidsを使用してください。複数の子関係のデータセットを操作する場合、IDENTITY属性を指定する列よりもGUIDを使用する方が使いやすいことがよくあります。これは、データベースから切断された状態のコードにguidをランダムに生成し、すべての変更を一度に送信できるためです。 guidが適切に生成されると、偶然に重複しにくくなります。アイデンティティ列では、親行を最初に挿入し、子データを追加する前に新しいアイデンティティを照会する必要があります。次に、データベースにコミットする前に、すべての子レコードを新しい親IDで更新する必要があります。同じことが孫のためにも、また、世俗主義のためにも同じです。それは不必要で平凡なような多くの仕事を築きます。 IDENTITY仕様を持たないランダムな整数を使用することでGuidsに似たようなことができますが、時間の経過とともにレコードを追加すると衝突の可能性が大きく高まります。 (Guid.NewGuid()はランダムなInt128に似ています - まだ存在しません)。

変更されない小さな参照リストや複数のデータベース間で複製されないデータに対しては、Byte(TinyInt)、Int16(SmallInt)、Int32/UInt16(Int)、Int64/UInt32(BigInt)を使用します。

(権限、アプリケーションの設定、色の名前など)私はあなたがGUIDまたは長いを使用している場合、インデックスは関係なく、に対してクエリを実行するだけの時間がかかります想像してみてください。とにかく128ビットより大きいインデックスされたテーブルの他のフィールド(通常、ユーザーテーブルのユーザー名など)があります。 GuidsとIntegersの違いは、メモリ内のインデックスのサイズだけでなく、インデックスを作成して再構築する時間です。データベーストランザクションの大半は、しばしば読んでいます。書き込みは最小限です。最適化されていない結合表、不適切なページング、または索引が欠落しているため、データベースからの読取りを最適化することに集中します。

何かと同様に、あなたのポイントを証明するのが最善のことです。 2つのテーブルを持つテストデータベースを作成します。 1つは整数/ longの主キーを持ち、もう1つはguidを持ちます。それぞれにN-Million行を配置します。 CRUD操作(作成、読み取り、更新、削除)中のそれぞれのパフォーマンスを監視します。パフォーマンスヒットはありますが、重要ではないことがわかります。

サーバは、デバッグ環境やCPU、メモリ、ハードドライブ(特にRAID)のI/Oを占めるその他のアプリケーションがないボックスで実行されることがよくあります。開発環境だけでは、パフォーマンスのアイデアが得られます。

関連する問題