web-dev-qa-db-ja.com

既存の非分割テーブルを分割する方法

データを含む既存のテーブルがあります。

dbo.Test (col1,col2,col3....) ON [PRIMARY]

このテーブルを次のようにパーティション分割するように変更する必要があります。

dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)

テーブルを削除して再作成せずにこれを実現するにはどうすればよいですか?

22
343

テーブルを分割するには、以下の簡単な手順に従います。

  • 最初に パーティション関数パーティションスキーム を作成します
  • その後、テーブルを分割できます。
  • テーブルにクラスター化インデックスがある場合、それを削除して適切なパーティションに再作成する必要があります。または、DROP_EXISTING句を使用して、クラスター化インデックスを再作成します。
  • テーブルにクラスター化インデックスがない場合は、パーティション構成を使用して適切なパーティションにインデックスを作成できます。
  • また、Enterprise EditionONLINE=ON CREATE INDEXステートメントのオプション。アプリケーションのダウンタイムを最小限に抑えます。 ONLINEオプションを使用してインデックスが再構築されている間、パフォーマンスが低下することに注意してください。

パーティショニングを自動化するには、 SQL Server Partition Management Utility または SQL Server Partitioned Table Framework を使用できますcodeplexでも利用できます。

いくつかの良いリソース:

23
Kin Shah

テーブルにクラスター化インデックスがあるかどうかは指定しないので、すべてのオプションを見ていきましょう。

この例のパーティション関数、パーティション構成、テーブルを使用します。

_CREATE PARTITION FUNCTION pf1(INT) AS RANGE LEFT FOR VALUES(10,20,30,40);
GO
CREATE PARTITION SCHEME ps1 AS PARTITION pf1 ALL TO ([PRIMARY])
GO
CREATE TABLE dbo.pt(pc INT NOT NULL, id INT NOT NULL) ON [PRIMARY];
GO
_

1。テーブルには、制約によって作成されなかったクラスター化インデックスがあります。

これが最も簡単なケースです。 _CREATE INDEX_句を指定した_DROP_EXISTING_ステートメントを使用して、テーブルをパーティション構成に移動できます。

このクラスター化インデックスが作成された例を想定します。

_CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];
_

このテーブルをパーティション分割するために、クラスター化インデックスにはパーティション列(この場合はpt)がキーの一部として含まれています。次のステートメントは、クラスター化インデックスを変更して、パーティション列を含め、それを同時にパーティション分割します。

_CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;
_

_DROP_Existing_句は、新しいインデックスを作成する前に、既存のインデックスを自動的に削除します。これは、非クラスター化インデックスが1回だけ再構築されるため、別の_DROP INDEX_よりも優先されます。

2。テーブルに_PRIMARY KEY_またはUNIQUE制約の一部であるクラスター化インデックスがあり、キーの一部としてパーティション列が含まれている

これはまだ簡単で、前のものとよく似ています。

この_PRIMARY KEY_制約がテーブルに作成されていると想定します。

_ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];
_

これで、1で使用したのと同じ再作成スクリプトを実行できます。

_CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;
_

。テーブルには、パーティション列を含まないが_PRIMARY KEY_またはUNIQUE制約の一部として作成されたクラスター化インデックスがあります

頑張ってください。事後、_PRIMARY KEY_またはUNIQUE制約の定義を変更することはできません。唯一のオプションは、制約を削除してから、パーティション列を含む制約を再作成するか、パーティション列を含む制約とは無関係にクラスター化インデックスを作成することです。 2番目のケースでは、パーティション列を含めずに、制約NONCLUSTEREDを再作成できます。この制約は調整されていない(つまり、サポートするインデックスがパーティション分割されていない)ため、ディスク上のどこに配置するかを指定する必要があります。

テーブルに次のような主キーがあるとします。

_ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];
_

このテーブルを分割するには、まず制約を削除する必要があります。

_ALTER TABLE dbo.pt DROP CONSTRAINT ptc;
_

次に、パーティション化されたクラスター化インデックスを作成する必要があります。

_CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;
_

_PRIMARY KEY_制約を非整列で再作成する場合は、次のようにします。

_ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];
_

4。テーブルにクラスター化インデックスがありません

この場合、ほとんどの場合、クラスター化インデックスを作成してパーティションを確立することをお勧めします。前に見たcreate indexステートメントを使用できます。

_CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;
_

ただし、クラスター化インデックスを作成しない正当な理由がある場合は、次の2段階のアプローチで回避できます。残念ながら、この変更を直接行う方法はありません。

テーブルにクラスター化インデックスがないと仮定します。テーブルを分割するには、最初に_CLUSTERED UNIQUE_制約を作成する必要があります。 (_CLUSTERED PRIMARY KEY_制約を使用することもできます)。一意の列の組み合わせがある場合、それは簡単な手順です。

_ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);
_

制約が作成されたら、それを再度ドロップし、同時にテーブルを新しいパーティション構成に「移動」できます。

_ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));
_

一意の列の組み合わせがない場合は、運が悪いです。この場合の唯一の選択肢は、新しい列を追加して一意の値を入力することです。テーブルがかなり小さい場合は、次のようにすることができます。

_ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);
_

ただし、すべての行が評価されるまでは、排他的なテーブルロックがかかります。テーブルのサイズにもよりますが、これにはかなりの時間がかかります。その列が作成された後、上記の2つの手順に従って最初にUNIQUE制約を作成し、次にすぐにそれを再度ドロップします。その後、列を再度ドロップすることもできます。これらのすべての手順はかなり煩わしいので、テーブルにクラスター化インデックスを作成する方が良いでしょう。それはユニークである必要さえありません。


Enterprise Editionを使用している場合は、上記のほとんどのステートメントでWITH(ONLINE=ON)句を使用できます。これにより、他の接続でテーブルを使用できるようになります。ただし、その間、パフォーマンスに影響があります。

53
Sebastian Meine