[解決済み] GUIDを主キーとして使用する場合のベストプラクティス、特にパフォーマンスに関して教えてください。[クローズド]。
質問
私は、ほとんどのテーブルでGUIDを主キーとして使用しているアプリケーションを持っていますが、GUIDを主キーとして使用する場合、パフォーマンスに関する問題があると読んだことがあります。正直なところ、私は何の問題も見ていませんが、新しいアプリケーションを始めようとしていて、まだGUIDを主キーとして使いたいのですが、複合主キー(GUIDと多分別のフィールド)を使おうと思っていました。
GUIDを使用しているのは、本番環境、テスト環境、開発環境など異なる環境がある場合や、データベース間のデータ移行を行う場合に、管理がしやすいからです。
私はEntity Framework 4.3を使用し、データベースに挿入する前に、アプリケーションコードでGuidを割り当てたいと思っています。(すなわち、私はSQLにGuidを生成させたくありません)。
GUIDベースの主キーを作成する際のベストプラクティスは何ですか?このアプローチに関連すると思われるパフォーマンスの低下を避けるには?
どのように解決するのですか?
GUIDはプライマリキーとして自然な選択と思われるかもしれません。しかし、私が強くお勧めするのは しないこと は、GUIDカラムを クラスタリングキー SQL Serverはデフォルトでそうなっています。
本当に2つの問題を分けて考える必要があるんですね。
-
その 主キー は論理的な構成要素で、テーブル内のすべての行を一意的かつ確実に識別するためのキーの候補のひとつです。これは、どんなものでもよいのです。
INT
, aGUID
文字列 - シナリオに最も適したものを選んでください。 -
その クラスタリングキー (テーブル上の "クラスタ化インデックス" を定義するカラム) - これは 物理的 ストレージに関連するもので、ここでは、小さくて安定した、増え続けるデータ型が最適です - 。
INT
またはBIGINT
をデフォルトのオプションに設定します。
デフォルトでは、SQL Serverテーブルの主キーはクラスタリングキーとしても使用されますが、そうである必要はありません。GUIDベースのプライマリ/クラスタキーを2つのキーに分割し、プライマリ(論理)キーはGUIDで、クラスタリング(順序)キーは別個の
INT IDENTITY(1,1)
カラムを使用します。
として
キンバリー・トリップ
- は、「インデックスの女王」をはじめ、多くの人が何度も述べています。
GUID
なぜなら、そのランダム性により、ページやインデックスの断片化を引き起こし、一般にパフォーマンスが低下するからです。
そうなんです。
newsequentialid()
SQL Server 2005 以降のバージョンでは、完全なシーケンシャルではありません。
GUID
- が、ちょっとだけ目立たなくなりました。
テーブルのクラスタリングキーは、テーブル上の非クラスタリングインデックスの各エントリに追加されるため、できるだけ小さくする必要があります。一般に
INT
は20億行以上あれば、ほとんどのテーブルで十分なはずです。
GUID
をクラスタリングのキーとして使用することで、ディスクとサーバーのメモリに数百メガバイトのストレージを節約することができます。
簡単な計算
INT
vs.
GUID
を主キーとクラスタリングキーとして使用します。
- 1,000,000行のベーステーブル(3.8MB vs. 15.26MB)
- 6つの非クラスタ化インデックス (22.89 MB vs. 91.55 MB)
TOTAL: 25 MB vs. 106 MB - しかも、これはたった1つのテーブルの上での話です。
キンバリー・トリップの素晴らしい文章を読んで、もう一度読んで、消化してください。これはSQL Serverのインデックス作成に関する福音書です。
- PRIMARY KEYおよび/またはClustered KeyとしてのGUID
- クラスター化インデックスの議論は続く
- 増え続けるクラスタリング・キー - クラスタ化インデックス論争......再び!
- ディスク容量が安い - それは ではない ポイント
追記:もちろん、数百行や数千行を扱うだけであれば、これらの議論のほとんどはあまり影響を及ぼさないでしょう。しかし、数万行、数十万行になると、あるいは数百万行になると......。 では これらの点は、非常に重要であり、理解することが非常に重要になります。
アップデートしてください。
を使用したい場合は
PKGUID
カラムを主キー (ただしクラスタリングキーではない) とし、別のカラムである
MYINT
(
INT 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
この方法は、既存のシステムのパフォーマンスを向上させるためのリエンジニアリングが必要な場合に有効なオプションとなります。新しいシステムで、ゼロから始める場合、そしてレプリケーションのシナリオでない場合、私は常に以下を選びます。
ID INT IDENTITY(1,1)
をクラスタ化された主キーとして使用します。
関連
-
[解決済み】各GROUP BY式は、外部参照でない列を少なくとも1つ含む必要があります。
-
[解決済み] 更新時のSqlエラー : UPDATE ステートメントが FOREIGN KEY 制約と競合しています。
-
[解決済み] TEXTIMAGE_ON [PRIMARY]とは何ですか?
-
[解決済み] try catch ブロックで @@trancount > 0 を確認する必要があるのはどのような場合ですか?
-
[解決済み] 等値演算で "SQL_Latin1_General_CP1_CI_AS" と "Latin1_General_CI_AS" の照合の競合を解決できない
-
[解決済み] sql文の角括弧[]の使い方を教えてください。
-
[解決済み] T-SQL XOR 演算子
-
[解決済み] SQL Server の .sql ファイルとは何ですか?
-
[解決済み] SQL ServerでCreateステートメントを使用してtempテーブルを作成する方法は?
-
[解決済み】GUID / UUIDデータベースキーの利点と欠点
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PRIMARY KEY制約に違反しました。オブジェクトに重複したキーを挿入できない
-
[解決済み] SQL Server データベース復元エラー: 指定されたキャストは無効です。(SqlManagerUI)
-
[解決済み] 結果を分割するためのSQLの小数点以下の値
-
[解決済み] テーブルの上位1レコードを更新する sql server [重複].
-
[解決済み] 関数内から実行できるのは、関数と一部の拡張ストアドプロシージャのみです。
-
[解決済み] シンプルに保つ、クエリで複数のCTEを行う方法
-
[解決済み] データベースとスキーマの違い
-
[解決済み] SQL ServerでCreateステートメントを使用してtempテーブルを作成する方法は?
-
[解決済み] SQL ServerにおけるXOR
-
[解決済み] データベース内の全テーブルのサイズを取得する