7

この質問は、挿入が行われたときにクラスター化インデックス内のデータの再編成で何が起こるかに関するものです。クラスター化インデックス内のデータを再編成するには、ディスク上のデータの物理レイアウトを変更する必要があるため、クラスター化インデックスを使用しないテーブルよりも、クラスター化インデックスを使用するテーブルで挿入を行う方がコストがかかると思います。仕事で出くわした例を除いて、私の質問をどのように表現すればよいかわかりません。

テーブル (ジャンク) があり、テーブルに対して実行される 2 つのクエリがあるとします。最初のクエリは名前で検索し、2 番目のクエリは名前と何かで検索します。データベースで作業していると、次のように、各クエリをサポートするために 1 つずつ、2 つのインデックスでテーブルが作成されていることがわかりました。

--drop table Junk1
CREATE TABLE Junk1
(
    Name char(5),  
    Something char(5),
    WhoCares int
)

CREATE CLUSTERED INDEX IX_Name ON Junk1
(
    Name
)

CREATE NONCLUSTERED INDEX IX_Name_Something ON Junk1
(
    Name, Something
)

2 つのインデックスを調べたところ、IX_Name_Something は名前で検索する任意のクエリで使用できるため、IX_Name は冗長であるように見えます。したがって、IX_Name を削除し、代わりに IX_Name_Something をクラスター化インデックスにします。

--drop table Junk2
CREATE TABLE Junk2
(
    Name char(5),  
    Something char(5),
    WhoCares int
)

CREATE CLUSTERED INDEX IX_Name_Something ON Junk2
(
    Name, Something
)

より効率的な挿入/削除が行われるため、最初のインデックス作成スキームを維持する必要があると誰かが提案しました (名前と何かの更新について心配する必要はないと仮定します)。それは理にかなっていますか?維持する必要があるインデックスが 1 つ少ないことを意味するため、2 番目のインデックス作成方法の方が優れていると思います。

この特定の例についての洞察や、クラスター化インデックスのメンテナンスに関する詳細情報を教えていただければ幸いです。

4

3 に答える 3

10

はい、最適ではないクラスター化インデックスがある場合、既存のテーブル (またはそのページ) の途中に挿入すると、コストがかかる可能性があります。最悪の場合はページ分割です。ページの行の半分を別の場所に移動する必要があり、インデックス (そのテーブルのクラスター化されていないインデックスを含む) を更新する必要があります。

適切なクラスター化インデックス (理想的には次のようなもの) を使用することで、この問題を軽減できます。

  • 狭い (1 つのフィールドのみ、できるだけ小さい)
  • 静的 (変化しない)
  • 一意 (SQL Server が 4 バイトの一意識別子を行に追加する必要がないように)
  • 増え続ける (INT IDENTITY のように)

クラスター化されていないすべてのインデックスのすべてのエントリにもクラスター化キーが含まれるため、狭いキー (理想的には 1 つの INT) が必要です。クラスター化キーに多くの列を配置したくない場合も、そこに VARCHAR(200) のようなものを置きたいですか!

クラスター化されたインデックスが増加し続けるため、ページ分割のケースは見られません。発生する可能性がある唯一の断片化は、削除によるものです (「スイスチーズ」問題)。

索引付けに関する Kimberly Tripp のエクセルレットのブログ記事をチェックしてください。

テーブル (ジャンク) があり、テーブルに対して実行される 2 つのクエリがあるとします。最初のクエリは名前で検索し、2 番目のクエリは名前と何かで検索します。データベースで作業していると、次のように、各クエリをサポートするために 1 つずつ、2 つのインデックスでテーブルが作成されていることがわかりました。

それは絶対に必要では(Name, Something)ありません.最新の状態に保つ必要があります)。WHERE Name = abcName

したがって、基本的には に 1 つのインデックスしか必要ありません。(Name, Something)私はあなたに同意します。このテーブルに他のインデックスがない場合は、これをクラスター化されたキーにすることができます。そのキーは増え続けることはなく、変更される可能性もあるため (そうですか?)、これはあまり良いアイデアではないかもしれません。

もう 1 つのオプションは、その上にサロゲートID INT IDENTITYとクラスターを導入することです。これには 2 つの利点があります。

  • それはすべて、増加し続けることを含め、適切なクラスター化されたキーであるべきです->ページ分割とINSERT操作のパフォーマンスに問題はありません
  • クラスタリング キーを持つことのすべての利点を引き続き得ることができます (Kim Tripps のブログ投稿を参照してください - ほとんどの場合、クラスタ化されたテーブルはヒープよりも望ましいです)。
于 2010-05-27T20:31:54.807 に答える
0

より効率的な挿入/削除につながるため、最初のインデックス作成スキームを維持する必要があると誰かが提案しました

それは虚偽の主張です。順序付きデータは順序付きデータであり、同じ IO が実行されます。

SET STATISTICS IO ON
-- your insert statement here
于 2010-05-28T13:40:52.797 に答える
0

クラスター化インデックスは、2 つ以上ではなく 1 つの列にのみ作成できるため、顧客のフルネームに対するワイルドカード クエリなど、アプリで主にクエリを実行する列を選択します (説明を参照) 。

于 2010-08-06T14:56:24.133 に答える