Comment partitionner une table non partitionnée existante

22

J'ai une table existante avec des données:

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

J'ai besoin de changer cette table pour qu'elle soit partitionnée comme ceci:

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

Comment puis-je y parvenir sans supprimer et recréer la table?

343
la source

Réponses:

23

Pour partitionner une table, vous pouvez suivre les étapes ci-dessous:

  • créez d'abord une fonction de partition et un schéma de partition
  • Après cela, vous pouvez partitionner une table.
  • SI votre table a un index clusterisé, vous devez le supprimer et le recréer sur la partition de droite ou vous pouvez utiliser la DROP_EXISTINGclause pour recréer l'index clusterisé.
  • Si votre table n'a pas d'index clusterisé, vous pouvez simplement en créer un sur la partition de droite à l'aide du schéma de partition.
  • Enterprise Edition a également la ONLINE=ONpossibilité d'utiliser l' option de l'instruction CREATE INDEX pour minimiser les temps d'arrêt de votre application. Notez que vous verrez une dégradation des performances lors de la reconstruction de l'index à l'aide de l'option EN LIGNE.

POUR automatiser le partitionnement, vous pouvez également utiliser l' utilitaire SQL Server Partition Management ou SQL Server Partitioned Table Framework disponible sur codeplex.

Quelques bonnes ressources:

Kin Shah
la source
53

Vous ne spécifiez pas si votre table a un index clusterisé ou non, nous allons donc parcourir toutes les options.

Je vais utiliser cet exemple de fonction de partition, de schéma de partition et de table:

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. Votre table possède un index cluster qui n'a pas été créé par une contrainte.

C'est le cas le plus simple. Vous pouvez simplement utiliser l' CREATE INDEXinstruction avec la DROP_EXISTINGclause pour déplacer la table vers le schéma de partition.

Supposons pour l'exemple que cet index cluster a été créé:

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

Pour partitionner cette table, l'index cluster a inclus la colonne de partition (pt dans notre cas) dans le cadre de la clé. Cette instruction modifie l'index cluster pour inclure la colonne de partition et la partitionne en même temps:

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

La DROP_Existingclause supprime automatiquement l'index existant avant d'en créer un nouveau. Ceci est préférable à un autre DROP INDEXcar il provoque la reconstruction des index non clusterisés une seule fois.

2. Votre table a un index cluster qui fait partie d'une contrainte PRIMARY KEYor UNIQUEet contient la colonne de partition en tant que partie de la clé

Celui-ci est toujours facile et très similaire au précédent.

Supposons que cette PRIMARY KEYcontrainte ait été créée sur la table:

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

Maintenant, vous pouvez simplement exécuter le même script de recréation que nous avons utilisé dans 1:

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

3. La table a un index cluster qui n'inclut pas la colonne de partition mais a été créé dans le cadre d'une contrainte PRIMARY KEYorUNIQUE

Mauvais chance. Vous ne pouvez pas modifier la définition d'un PRIMARY KEYou d' une UNIQUEcontrainte après coup. Votre seule option consiste à supprimer la contrainte, puis à la recréer, y compris la colonne de partition, ou à créer un index clusterisé indépendant de la contrainte qui inclut la colonne de partition. Dans le second cas, vous pouvez recréer la contrainteNONCLUSTERED sans inclure la colonne de partition. Parce que maintenant cette contrainte n'est pas alignée (ce qui signifie que son index de prise en charge n'est pas partitionné), vous devez spécifier où la placer sur le disque.

Supposons que la table ait une clé primaire comme celle-ci:

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

Pour partitionner cette table, vous devez d'abord supprimer la contrainte:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Ensuite, vous devez créer l'index clusterisé partitionné:

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

Si vous choisissez de recréer la PRIMARY KEYcontrainte non alignée, vous pouvez le faire comme ceci:

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

4. Votre table n'a pas d'index clusterisé

Dans ce cas, il est recommandé dans la plupart des cas de simplement créer un index cluster pour établir le partitionnement. Vous pouvez utiliser l'instruction create index vue précédemment pour cela:

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

Cependant, si vous avez une bonne raison de ne pas créer d'index cluster, vous pouvez vous en sortir avec l'approche en deux étapes suivante. Malheureusement, il n'y a aucun moyen direct d'effectuer ce changement.

Supposons que votre table ne possède pas d'index cluster. Pour partitionner la table, vous devez d'abord créer une CLUSTERED UNIQUEcontrainte. (Vous pouvez également utiliser une CLUSTERED PRIMARY KEYcontrainte). Si vous avez une combinaison de colonnes unique qui est une étape simple:

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

Une fois la contrainte créée, vous pouvez la supprimer à nouveau et "déplacer" la table vers le nouveau schéma de partition en même temps:

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

Si vous n'avez pas de combinaison de colonnes unique, vous n'avez pas de chance. Dans ce cas, votre seule option est d'ajouter une nouvelle colonne et de la remplir avec des valeurs uniques. Si la table est raisonnablement petite, vous pouvez faire quelque chose comme ceci:

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

Cependant, cela prendra un verrou de table exclusif jusqu'à ce que toutes les lignes soient évaluées. Selon la taille de la table, cela peut durer un certain temps. Une fois cette colonne créée, suivez les deux étapes ci-dessus pour créer d'abord la UNIQUEcontrainte, puis la supprimer à nouveau immédiatement. Ensuite, vous pouvez également supprimer à nouveau la colonne. Toutes ces étapes sont assez intrusives, il est donc préférable de simplement créer un index cluster sur la table. Cela n'a même pas besoin d'être unique.


Si vous avez Enterprise Edition, vous pouvez utiliser la WITH(ONLINE=ON)clause sur la plupart des instructions ci-dessus. Cela gardera votre table à la disposition d'autres connexions. Cependant, il y aura un impact sur les performances pendant cette période.

Sebastian Meine
la source
1
Excellent, Sabastian! Tout simplement excellent! Juste pour ajouter au n ° 3 ci-dessus ... si vous souhaitez utiliser SWITCH in ou out, tous les index doivent être alignés. Faire un PK non clusterisé et non aligné ne vous permettra pas de faire un SWITCH à moins que vous ne preniez les étapes pour supprimer l'index en premier, faire le SWITCH (quelle que soit la direction dans laquelle il se trouve) et reconstruire l'index. C'est très souvent encore plus rapide que de faire l'équivalent avec des suppressions et, bien sûr, si vous n'avez pas besoin d'utiliser SWITCH, ce ne sera pas un problème.
Jeff Moden