web-dev-qa-db-fra.com

Comment partitionner une table non partitionnée existante

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?

22
343

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

  • créez d'abord un fonction de partition et 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 bonne partition ou vous pouvez utiliser DROP_EXISTING clause 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.
  • De plus Enterprise Edition a la flexibilité d'utiliser le ONLINE=ON 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 utiliser Utilitaire de gestion de partition SQL Server ou Framework de table partitionnée SQL Server également disponible sur codeplex.

Quelques bonnes ressources:

23
Kin Shah

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

C'est le cas le plus simple. Vous pouvez simplement utiliser l'instruction CREATE INDEX Avec la clause DROP_EXISTING 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 clause DROP_Existing Supprime automatiquement l'index existant avant d'en créer un nouveau. Ceci est préférable à un DROP INDEX Séparé car 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 KEY Ou UNIQUE et contient la colonne de partition comme partie de la clé

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

Supposons que cette contrainte PRIMARY KEY 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) ;

. 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 KEY Ou UNIQUE

Mauvais chance. Vous ne pouvez pas modifier la définition d'une contrainte PRIMARY KEY Ou UNIQUE 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 en cluster indépendant de la contrainte qui inclut la colonne de partition. Dans le second cas, vous pouvez recréer la contrainte NONCLUSTERED 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 contrainte PRIMARY KEY 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 cluster

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 contrainte CLUSTERED UNIQUE. (Vous pouvez également utiliser une contrainte CLUSTERED PRIMARY KEY). 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 contrainte UNIQUE 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 clause WITH(ONLINE=ON) 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.

53
Sebastian Meine