sql >> データベース >  >> RDS >> Sqlserver

特にパフォーマンスに関して、GUIDを主キーとして使用するためのベストプラクティスは何ですか?

    GUIDは、主キーの自然な選択のように思われるかもしれません。本当に必要な場合は、テーブルの主キーにGUIDを使用することを主張することもできます。 やらないことを強くお勧めします GUID列をクラスタリングキーとして使用します 、特に指定しない限り、SQLServerはデフォルトで実行します。

    本当に2つの問題を区別する必要があります:

    1. 主キー は論理構造であり、テーブル内のすべての行を一意かつ確実に識別する候補キーの1つです。これは実際には何でもかまいません-INTGUID 、文字列-シナリオに最も適したものを選択してください。

    2. クラスタリングキー (テーブルの「クラスター化インデックス」を定義する1つまたは複数の列)-これは物理的 ストレージ関連のことですが、ここでは、小さくて安定した、増え続けるデータ型が最適です-INT またはBIGINT デフォルトオプションとして。

    デフォルトでは、SQL Serverテーブルの主キーはクラスタリングキーとしても使用されますが、そのようにする必要はありません。以前のGUIDベースのプライマリ/クラスター化キーを2つの別個のキー(GUIDのプライマリ(論理)キーと別個のINT IDENTITY(1,1) 列。

    キンバリー・トリップ(インデックス作成の女王)や他の人たちが何度も述べているように、GUID クラスタリングキーは最適ではないため、ランダムであるため、ページとインデックスの断片化が大きくなり、一般的にパフォーマンスが低下します。

    はい、わかっています-newsequentialid()があります SQL Server 2005以降では、それでも完全にシーケンシャルではないため、GUIDと同じ問題が発生します。 -少し目立たないように。

    次に、考慮すべき別の問題があります。テーブルのクラスタリングキーは、テーブルのすべての非クラスター化インデックスのすべてのエントリにも追加されます。したがって、可能な限り小さいことを確認する必要があります。通常、INT GUIDと比較すると、大多数のテーブルには20億行以上で十分です。 クラスタリングキーとして、ディスクとサーバーメモリに数百メガバイトのストレージを節約できます。

    クイック計算-INTを使用 対GUID プライマリキーおよびクラスタリングキーとして:

    • 1'000'000行のベーステーブル(3.8MB対15.26MB)
    • 6つの非クラスター化インデックス(22.89MB対91.55MB)

    合計:25MB対106MB -そしてそれはただ1つのテーブルにあります!

    もう少し考えてみてください-キンバリー・トリップの素晴らしいもの-読んで、もう一度読んで、消化してください!これは、SQLServerのインデックス作成の福音です。

    • 主キーおよび/またはクラスター化キーとしてのGUID
    • クラスター化されたインデックスの議論は続く
    • 増え続けるクラスタリングキー-クラスター化されたインデックスの討論..........再び!
    • ディスクスペースは安価です-それはそうではありません ポイント!

    PS:もちろん、数百行または数千行を扱っている場合、これらの引数のほとんどは実際にはあまり影響を与えません。ただし、数万または数十万の行に入る場合、または数百万の行を数え始めた場合-その後 これらの点は非常に重要であり、理解することが非常に重要になります。

    更新: PKGUIDが必要な場合 主キー(クラスタリングキーではない)としての列、および別の列MYINTINT IDENTITY )クラスタリングキーとして-これを使用します:

    CREATE TABLE dbo.MyTable
    (PKGUID UNIQUEIDENTIFIER NOT NULL,
     MyINT INT IDENTITY(1,1) NOT NULL,
     .... add more columns as needed ...... )
    
    ALTER TABLE dbo.MyTable
    ADD CONSTRAINT PK_MyTable
    PRIMARY KEY NONCLUSTERED (PKGUID)
    
    CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
    

    基本的に:明示的にする必要があります PRIMARY KEYに伝えます NONCLUSTEREDであるという制約 (それ以外の場合は、デフォルトでクラスター化されたインデックスとして作成されます)-次に、CLUSTEREDとして定義された2番目のインデックスを作成します。

    これは機能します。パフォーマンスのために「再設計」する必要がある既存のシステムがある場合は、これは有効なオプションです。新しいシステムの場合、最初から始めて、レプリケーションシナリオを使用していない場合は、常にID INT IDENTITY(1,1)を選択します。 クラスタ化された主キーとして-他の何よりもはるかに効率的です!



    1. 最初の列の値が同じ場合は、2番目の列の値を連結します

    2. mysqliまたは死ぬ、それは死ぬ必要がありますか?

    3. SQLServer2017管理ツール

    4. MySQLSELECTインクリメントカウンター