6

テーブルの主キーである 2 つの列にクラスター化インデックスを持つテーブルがあります。次のように定義されています。

ALTER TABLE Table ADD  CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED 
(
  [ColA] ASC,
  [ColB] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

このクラスター化インデックス PK を削除し、次のようにクラスター化インデックスを追加し、以下に示す非クラスター化インデックスを使用して主キー制約を追加したいと考えています。

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table] 
(
  [ColC] ASC,
  [ColA] ASC,
  [ColD] ASC,
  [ColE] ASC,
  [ColF] ASC,
  [ColG] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,     DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = OFF) ON [PRIMARY]

ALTER TABLE Table ADD CONSTRAINT
  PK_Table PRIMARY KEY NONCLUSTERED 
  (
    ColA,
    ColB
  ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

PK クラスター化インデックスを削除してから、新しいクラスター化インデックスを追加し、次に非クラスター化主キー インデックスを追加するつもりでしたが、既存のクラスター化インデックスを削除すると、テーブル データの順序が変更されることがわかりました (こちらの回答を参照してください) 。 SQL 2005 でクラスター化された主キーを削除すると発生します)、これは必要ではないと思います。テーブルは 1 TB をノックしているので、不要な並べ替えは避けたいと思っています。

私の質問は、既存の構造から望ましい構造に移行するための最良の方法は何ですか?

編集:明確にしたいだけです。テーブルは 1 TB ですが、残念ながら一時テーブルを作成するスペースがありません。一時テーブルを作成せずにそれを行う方法があれば教えてください。

4

4 に答える 4

11

これはあなたの質問に対する完全な答えではありませんが、テーブルに他のインデックスがある場合は、最初にそれらを削除してください。そうしないと、SQL Server は、クラスター化インデックスを削除するときにそれらをすべて再構築し、新しいクラスター化インデックスを追加し直すときにそれらをすべて再構築する必要があります。通常の手順は次のとおりです。

  1. 非クラスター化インデックスをすべて削除する
  2. クラスター化インデックスを削除する
  3. 新しいクラスター化インデックスを追加
  4. すべての非クラスター化インデックスを元に戻す
于 2009-04-01T14:51:36.290 に答える
8

テーブルのサイズが最大 1 TB になり、おそらく大量の行が含まれている場合は、クラスター化インデックスをそれほど太くしないことを強くお勧めします!

まず第一に、クラスター化されたインデックスを削除して再作成すると、すべてのデータが少なくとも 1 回シャッフルされます。それだけでも時間がかかります。

次に、作成しようとしている大きな複合クラスター化インデックスは、すべての非クラスター化インデックスのサイズを大幅に増加させます (ブックマーク ルックアップのために、各リーフ ノードにクラスター化インデックス値全体が含まれているため)。

問題はもっとです: なぜあなたはこれをやろうとしていますか?? 潜在的にクエリをカバーするために、これらの列に別の非クラスター化インデックスを追加することはできませんか? なぜこれがクラスター化インデックスでなければならないのですか?? メリットが見当たらない……。

インデックス作成、特にクラスター化インデックスの議論の詳細については、Kimberly Tripp のSQL Server インデックスに関するブログを参照してください。非常に役立ちます。

マルク

于 2009-04-02T05:32:40.120 に答える
4
  1. 新しいテーブルを作成します。

    CREATE TABLE newtable (colA INT, colB INT)
    
    • 古いテーブルのすべての値を新しいテーブルに挿入します。

      INSERT INTO newtable SELECT * FROM テーブル

    • 古いテーブルを削除します。

      DROP TABLE テーブル

    • 新しいテーブルの名前を古いテーブルに変更します

      EXEC sp_rename 'newtable', 'table'

    • インデックスを構築します。

      ALTER TABLE Table ADD CONSTRAINT PK_Table PRIMARY KEY NONCLUSTERED (ColA, ColB ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [プライマリ]

于 2009-04-01T14:33:49.873 に答える