So partitionieren Sie eine vorhandene nicht partitionierte Tabelle

22

Ich habe eine vorhandene Tabelle mit Daten:

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

Ich muss diese Tabelle ändern, um sie so zu partitionieren:

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

Wie kann ich dies erreichen, ohne den Tisch fallen zu lassen und neu zu erstellen?

343
quelle

Antworten:

23

Gehen Sie wie folgt vor, um eine Tabelle zu partitionieren:

  • Erstellen Sie zunächst eine Partitionsfunktion und ein Partitionsschema
  • Danach können Sie eine Tabelle partitionieren.
  • Wenn Ihre Tabelle über einen Clustered-Index verfügt, müssen Sie diesen in der richtigen Partition ablegen und neu erstellen, oder Sie können mithilfe der DROP_EXISTINGKlausel den Clustered-Index neu erstellen.
  • Wenn Ihre Tabelle keinen Clustered-Index hat, können Sie einfach einen in der richtigen Partition mit dem Partitionsschema erstellen.
  • Auch die Enterprise Edition verfügt über die Flexibilität, die ONLINE=ONOption der Anweisung CREATE INDEX zu verwenden, um Ausfallzeiten für Ihre Anwendung zu minimieren. Beachten Sie, dass Sie eine Leistungsverschlechterung feststellen, während der Index mit der Option ONLINE neu erstellt wird.

Um die Partitionierung zu automatisieren, können Sie das Dienstprogramm SQL Server Partition Management oder SQL Server Partitioned Table Framework verwenden, die auch für Codeplex verfügbar sind.

Einige gute Ressourcen:

Kin Shah
quelle
53

Sie geben nicht an, ob Ihre Tabelle einen Clustered-Index hat oder nicht. Lassen Sie uns also alle Optionen durchgehen.

Ich werde diese Beispiel-Partitionsfunktion, das Partitionsschema und die Tabelle verwenden:

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. Ihre Tabelle verfügt über einen Clustered-Index, der nicht von einer Einschränkung erstellt wurde.

Dies ist der einfachste Fall. Sie können einfach die CREATE INDEXAnweisung mit der DROP_EXISTINGKlausel verwenden, um die Tabelle in das Partitionsschema zu verschieben.

Angenommen, für das Beispiel wurde dieser Clustered-Index erstellt:

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

Um diese Tabelle zu partitionieren, enthält der Clustered-Index die Partitionsspalte (in unserem Fall pt) als Teil des Schlüssels. Mit dieser Anweisung wird der Clustered-Index so geändert, dass er die Partitionsspalte enthält und gleichzeitig partitioniert:

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

Die DROP_ExistingKlausel entfernt automatisch den vorhandenen Index, bevor der neue erstellt wird. Dies wird einem separaten vorgezogen, DROP INDEXda dadurch die nicht gruppierten Indizes nur einmal neu erstellt werden.

2. Ihre Tabelle verfügt über einen Clustered-Index, der Teil einer PRIMARY KEYoder einer UNIQUEEinschränkung ist, und enthält die Partitionsspalte als Teil des Schlüssels

Dieser ist immer noch einfach und dem vorherigen sehr ähnlich.

Angenommen, diese PRIMARY KEYEinschränkung wurde für die Tabelle erstellt:

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

Jetzt können Sie dasselbe Skript zur Neuerstellung ausführen, das wir in 1 verwendet haben:

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

3. Die Tabelle verfügt über einen Clustered-Index, der die Partitionsspalte nicht enthält, jedoch als Teil einer PRIMARY KEYoder einer UNIQUEEinschränkung erstellt wurde

Pech. Sie können die Definition eines PRIMARY KEYoder einer UNIQUEEinschränkung nicht nachträglich ändern . Sie können die Einschränkung nur löschen und dann entweder einschließlich der Partitionsspalte neu erstellen oder einen Clustered-Index unabhängig von der Einschränkung erstellen, die die Partitionsspalte enthält. Im zweiten Fall können Sie die Einschränkung neu erstellen, NONCLUSTEREDohne die Partitionsspalte einzuschließen. Da diese Einschränkung jetzt nicht ausgerichtet ist (was bedeutet, dass der unterstützende Index nicht partitioniert ist), müssen Sie angeben, wo sie auf der Festplatte platziert werden soll.

Angenommen, die Tabelle hatte einen Primärschlüssel wie diesen:

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

Um diese Tabelle zu partitionieren, müssen Sie zuerst die Einschränkung löschen:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Dann müssen Sie den partitionierten Clustered-Index erstellen:

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

Wenn Sie die PRIMARY KEYEinschränkung ohne Ausrichtung neu erstellen möchten, können Sie dies folgendermaßen tun:

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

4. Ihre Tabelle hat keinen Clustered-Index

In diesem Fall wird in den meisten Fällen empfohlen, nur einen Clustered-Index zu erstellen, um die Partitionierung einzurichten. Dazu können Sie die zuvor angezeigte Anweisung create index verwenden:

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

Wenn Sie jedoch einen guten Grund haben, keinen Clustered-Index zu erstellen, können Sie den folgenden zweistufigen Ansatz anwenden. Leider gibt es keinen direkten Weg, um diese Änderung vorzunehmen.

Angenommen, Ihre Tabelle hat keinen Clustered-Index. Um die Tabelle zu partitionieren, müssen Sie zuerst eine CLUSTERED UNIQUEEinschränkung erstellen . (Sie können auch eine CLUSTERED PRIMARY KEYEinschränkung verwenden). Wenn Sie eine Spaltenkombination haben, die eindeutig ist, ist dies ein einfacher Schritt:

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

Nachdem die Einschränkung erstellt wurde, können Sie sie erneut löschen und die Tabelle gleichzeitig in das neue Partitionsschema verschieben:

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

Wenn Sie keine einzigartige Spaltenkombination haben, haben Sie Pech. In diesem Fall können Sie nur eine neue Spalte hinzufügen und diese mit eindeutigen Werten füllen. Wenn der Tisch einigermaßen klein ist, können Sie Folgendes tun:

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

Dies erfordert jedoch eine exklusive Tabellensperre, bis alle Zeilen bewertet sind. Abhängig von der Tischgröße kann dies eine Weile dauern. Nachdem diese Spalte erstellt wurde, führen Sie die beiden obigen Schritte aus, um zuerst die UNIQUEEinschränkung zu erstellen und sie dann sofort wieder zu löschen. Danach können Sie die Spalte auch wieder ablegen. Alle diese Schritte sind ziemlich aufdringlich, daher ist es wahrscheinlich besser, nur einen Clustered-Index für die Tabelle zu erstellen. Das muss nicht einmal einzigartig sein.


Wenn Sie über Enterprise Edition verfügen, können Sie die WITH(ONLINE=ON)Klausel für die meisten der obigen Anweisungen verwenden. Dadurch bleibt Ihr Tisch für andere Verbindungen verfügbar. In dieser Zeit wird es jedoch zu Leistungseinbußen kommen.

Sebastian Meine
quelle
1
Exzellent, Sabastian! Einfach rundum exzellent! Nur um zu # 3 oben hinzuzufügen ... wenn Sie SWITCH in oder out verwenden möchten, müssen alle Indizes ausgerichtet werden. Wenn Sie eine nicht gruppierte, nicht ausgerichtete PK erstellen, können Sie keinen SWITCH ausführen, es sei denn, Sie führen die Schritte aus, um den Index zuerst zu löschen, den SWITCH (in welcher Richtung auch immer) auszuführen und den Index neu zu erstellen. Das ist immer noch sehr oft schneller als das Entsprechende mit Löschvorgängen, und wenn Sie SWITCH nicht benötigen, ist das natürlich kein Problem.
Jeff Moden