1. ホーム
  2. sql

[解決済み] クラスター化 vs 非クラスター化

2023-01-02 19:11:08

質問

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 .