[解決済み] クラスター化 vs 非クラスター化
質問
SQL (Server 2008) に関する私の低レベルの知識は限られており、現在当社の DBA から挑戦を受けています。シナリオを説明させてください (私が正しいことを願って、明白なステートメントを挙げていますが、何か間違っていることを見つけたら、教えてください)。
私たちは人々の '裁判所命令' を保持するテーブルを持っています。テーブルを作成したとき、(名前:CourtOrder)、私はそのように作成しました。
CREATE TABLE dbo.CourtOrder
(
CourtOrderID INT NOT NULL IDENTITY(1,1), (Primary Key)
PersonId INT NOT NULL,
+ around 20 other fields of different types.
)
次に、私は主キーに非クラスタ化インデックスを適用しました(効率化のため)。私の理由は、これはユニークなフィールド (主キー) であり、インデックスを付けるべきであり、主に選択目的のために、しばしば
Select from table where primary key = ...
次に、私はPersonIdにCLUSTEREDインデックスを適用しました。その理由は、作業の大部分はある人物の注文を得ることであるため、特定の人物に対する注文を物理的にグループ化するためでした。そこで
select from mytable where personId = ...
今更ながら引っ張りだこです。主キーにクラスター化インデックスを、personIdに通常のインデックスを付けると良いと言われました。私にはとても不思議に思えます。まず、なぜユニークなカラムにクラスター化インデックスを置くのでしょうか?確かにそれはクラスター化インデックスの無駄遣いですね?私はユニークカラムには通常のインデックスを使用すると信じていました。また、インデックスをクラスタリングすると、別の列をクラスタリングできないことになります(1テーブルにつき1つですよね)。
私が間違いを犯したと言われた理由は、PersonId にクラスタ化されたインデックスを置くと挿入が遅くなると考えているからです。select の速度が 5% 向上する代わりに、inserts と update の速度が 95% 低下することになります。これは正しくて有効なのでしょうか?
PersonId をクラスタリングするため、PersonId に挿入または変更を加えるたびに、SQL Server はデータを並べ替えなければならないと言います。
それなら、なぜSQLにはCLUSTERED INDEXという概念があるのでしょうか。言われているほど遅いのでしょうか。最適なパフォーマンスを得るために、どのようにインデックスをセットアップすればよいのでしょうか。SELECT は INSERT よりも多く使用されると思っていましたが、INSERTS でロックの問題が発生しているとのことです。
誰かが私を助けてくれることを願っています。
どのように解決するのですか?
クラスタ化インデックスと非クラスタ化インデックスの区別は、クラスタ化インデックスが
がデータベース内の行の物理的な順序を決定することです。
. 言い換えれば、クラスタ化されたインデックスを適用すると
PersonId
で物理的にソートされることを意味します。
PersonId
で物理的にソートされていることを意味し、これに対するインデックス検索で行に直接たどり着くことができます(非クラスタ化インデックスでは、行の場所に直接たどり着くため、余計なステップが追加されます)。
とはいえ、これは
珍しい
は、主キーがクラスタ化インデックスでないことは珍しいですが、前代未聞ではありません。あなたのシナリオの問題は、実際にはあなたが想定していることの反対です。
一意
の値が欲しいのであって、重複しているわけではありません。クラスタ化インデックスは行の物理的な順序を決定するので、もしインデックスが一意でない列にある場合、サーバは重複するキー値を持つ行に背景値を追加しなければなりません(あなたの場合、同じ
PersonId
を持つ行) に背景値を追加する必要があり、これにより結合値 (キー + 背景値) が一意になります。
私が提案する唯一のものは
ではなく
をサロゲートキーとして使用することです (あなたの
CourtOrderId
) カラムを主キーとして使うのではなく、複合主キーの
PersonId
と他の一意に識別できるカラムまたはカラムのセットからなる複合主キーを使用します。しかし、それが不可能な場合 (あるいは実用的でない場合)、クラスタ化インデックスを
CourtOrderId
.
関連
-
[解決済み] SQL Server FOR EACH ループ
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] クラスター化インデックスと非クラスター化インデックスの実際の意味は何ですか?
-
[解決済み] 最初の行への結合方法
-
[解決済み] Sql Server 'Saving changes is not permitted' エラー ► テーブルの再作成を必要とする変更を保存しないようにする。
-
[解決済み] SQL Serverでレコードを削除した後、IDシードをリセットする。
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み] 既存のカラムにIDを追加する
-
[解決済み] Postgres でサブクエリを使用してテーブルの行を更新する
-
[解決済み] SQL Server - クラスタ化インデックスと非クラスタ化インデックスをいつ使うか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
解決策:java.sql.SQLException: ユーザー ''@'localhost'' (パスワード: YES を使用) のアクセスが拒否されました。
-
MHAクラスタエラーサマリーの構築
-
[解決済み] 複数の列でgroup byを使用する
-
[解決済み] クラスター化インデックスと非クラスター化インデックスの実際の意味は何ですか?
-
[解決済み] SQLのIN句をパラメータ化する
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] SQL Serverでストアドプロシージャ内のテキストを検索する
-
[解決済み] NOT IN vs NOT EXISTS
-
[解決済み] SQLでランダムな行を要求する方法は?
-
[解決済み] SQL ServerでINSERT INTOとしてデータをエクスポートする