既存の非パーティションテーブルをパーティション化する方法


22

データのある既存のテーブルがあります:

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

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

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

テーブルをドロップして再作成せずにこれを達成するにはどうすればよいですか?

回答:


23

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

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

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

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


53

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

この例のパーティション関数、パーティションスキーム、およびテーブルを使用します。

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句は、新しいインデックスを作成する前に既存のインデックスを自動的に削除します。これはDROP INDEX、非クラスター化インデックスが1回だけ再構築されるため、個別よりも優先されます。

2.テーブルにPRIMARY KEYor 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) ;

3.テーブルには、パーティション列を含まないが、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);

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


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


1
素晴らしい、サバスティアン!優れたフラットアウト!上記の#3に追加するだけです... SWITCH inまたはoutを使用する場合は、すべてのインデックスを揃える必要があります。非クラスター化、非整列PKの作成では、最初にインデックスを削除し、SWITCH(方向を問わず)を実行し、インデックスを再構築する手順を実行しない限り、SWITCHを実行できません。多くの場合、削除で同等の処理を行うよりも高速であり、もちろん、SWITCHを使用する必要がない場合は問題になりません。
ジェフモデン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.