SQL Server 2008 - Partitionnement et index clusterisés

16

Permettez-moi donc de préface en disant que je n'ai pas un contrôle total sur ma conception de base de données, de sorte que de nombreux aspects du système actuel ne peuvent pas être modifiés aux fins de ce scénario.

Les commentaires sur la façon de repenser les aspects de la conception sont probablement corrects mais inutiles :)

J'ai une très grande table, d'environ 150 champs de large et environ 600m de lignes, qui pilote un grand nombre de processus. C'est dans une situation d'entrepôt de données, donc nous n'avons AUCUNE mise à jour / insertions en dehors du processus de chargement planifié, il est donc fortement indexé.

Il a été décidé d'essayer de partitionner cette table, et j'ai quelques inquiétudes concernant l'indexation d'une table partitionnée. Je n'ai aucune expérience avec le partitionnement, donc toute entrée ou lien est apprécié. Je n'ai pas pu localiser précisément ce que je recherche sur BOL ou msdn.

Actuellement, nous nous regroupons sur un champ que nous appellerons et IncidentKeyqui n'est varchar(50)pas unique - nous pourrions avoir entre 1 à 100 enregistrements avec le même IK(pas de commentaires s'il vous plaît). Nous obtenons souvent de nouvelles données sur les anciens IncidentKeyenregistrements, ce n'est donc pas séquentiel non plus.

Je comprends que je dois inclure mon champ de partition IncidentDate, dans ma clé d'index cluster pour que la partition fonctionne correctement. Je pense que ça le serait IncidentKey, IncidentDate.

La question est de savoir comment fonctionne la mécanique d'un index clusterisé sur une clé en 2 parties dans une table partitionnée, si un enregistrement dans une "nouvelle" partition doit être avant un enregistrement dans une "ancienne" partition dans l'index clusterisé?

Par exemple, j'ai 5 enregistrements:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Si j'obtiens un nouvel enregistrement, ABC123, 2/1/2011il devra être dans l'index cluster AVANT XYZ999, 1/1/2010 . Comment cela marche-t-il?

J'assume la fragmentation et les pointeurs, mais je ne trouve aucune information sur le stockage physique et la configuration des index cluster non partitionnés sur des tables partitionnées avec des clés en deux parties.

JNK
la source
Pourquoi la décision de partitionner la table a-t-elle été prise? Quels sont les avantages attendus du partitionnement?
Remus Rusanu
@Remus - Je le fais en fait comme test, nous aurons donc une version partitionnée et une version non partitionnée. L'avantage escompté est une diminution des temps de chargement et des temps de génération d'index. Nous effectuons des opérations ETL mensuelles qui prennent environ une semaine et nous espérons que cela réduira considérablement ce temps. Nous avons également un déploiement d'environ 3 To que nous espérons réduire avec cela.
JNK

Réponses:

18

Une table partitionnée ressemble plus à une collection de tables individuelles assemblées. Donc, dans votre exemple de clustering par IncidentKeyet de partitionnement par IncidentDate, disons que la fonction de partitionnement divise les tables en deux partitions de sorte que 1/1/2010 soit dans la partition 1 et 7/1/2010 soit la partition deux. Les données seront disposées sur disque comme:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

À un niveau bas, il y a vraiment deux ensembles de lignes distincts. Est le processeur de requêtes qui donne l'illusion d'une table unique en créant des plans qui recherchent, analysent et mettent à jour tous les ensembles de lignes ensemble, comme un seul.

Toute ligne d'un index non clusterisé aura la clé d'index clusterisée à laquelle elle correspond, par exemple ABC123,7/1/2010. Étant donné que la clé d'index cluster contient toujours la colonne de clé de partitionnement, le moteur saura toujours dans quelle partition (ensemble de lignes) de l'index cluster pour rechercher cette valeur (dans ce cas, dans la partition 2).

Désormais, chaque fois que vous avez affaire à un partitionnement, vous devez déterminer si vos index NC seront alignés (l'index NC est partitionné exactement de la même manière que l'index cluster) ou non alignés (l'index NC n'est pas partitionné ou partitionné différemment de l'index cluster). . Les index non alignés sont plus flexibles, mais ils présentent certains inconvénients:

L'utilisation d'index alignés résout ces problèmes, mais apporte son propre ensemble de problèmes, car cette option de conception physique du stockage se répercute dans le modèle de données:

  • les index alignés signifient que les contraintes uniques ne peuvent plus être créées / appliquées (sauf pour la colonne de partitionnement)
  • toutes les clés étrangères référençant la table partitionnée doivent inclure la clé de partitionnement dans la relation (car la clé de partitionnement est, en raison de l'alignement, dans chaque index), ce qui à son tour nécessite que toutes les tables référençant la table partitionnée contiennent une valeur de colonne de clé de partitionnement. Pensez Orders-> OrderDetails, si les commandes ont OrderID mais sont partitionnées par OrderDate, alors OrderDetails doit contenir non seulement OrderID, mais aussi OrderDate, afin de déclarer correctement la contrainte de clé étrangère.

Ces effets que j'ai trouvés rarement évoqués au début d'un projet qui déploie le partitionnement, mais ils existent et ont de graves conséquences.

Si vous pensez que les index alignés sont un cas rare ou extrême, alors considérez ceci: dans de nombreux cas, la pierre angulaire des solutions ETL et de partitionnement est le basculement rapide des tables de transfert. Les opérations de basculement nécessitent des index alignés.

Oh, encore une chose: tout mon argument sur les clés étrangères et l'effet d'entraînement de l'ajout de la valeur de la colonne de partitionnement aux autres tables s'applique également aux jointures .

Remus Rusanu
la source
Parfait, c'est exactement ce que je cherchais. Nous devrons utiliser des index alignés b / c le swapping fait partie du tirage au sort pour ce que nous voulons faire avec cela. Nous faisons également une tonne de fonctions agrégées regroupant sur ce IncidentKeydomaine, ce qui, je pense, sera sérieusement entravé. J'apprécie tous les détails!
JNK
Habituellement, les avantages des opérations de commutation de partition l'emportent sur tous les problèmes.
Remus Rusanu
C'est notre espoir, nous verrons bientôt!
JNK
9

Lorsqu'un index cluster a plusieurs partitions, chaque partition a une structure B-tree qui contient les données pour cette partition spécifique. Par exemple, si un index cluster a quatre partitions, il y a quatre structures B-tree; un dans chaque partition. Réf. Structures d'index cluster

Lignes directrices spéciales pour les index partitionnés

Vous pouvez reconstruire des partitions spécifiques d'un index partitionné.

par exemple

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Blé Mitch
la source
+1 Pour le lien, j'avais lu les directives spéciales mais j'ai raté ce paragraphe. Question de suivi - nous faisons beaucoup d'agrégation sur le IncidentKeyterrain, pensez-vous que cela nuirait aux performances (je me rends compte que je devrai encore faire des tests)?
JNK
Je ne connais pas toutes vos circonstances spécifiques mais il me semble que vous feriez mieux de partitionner par IncidentDate?
Mitch Wheat
Nous partitionnons à la date, mais la clé en cluster est activée IncidentKey- nous faisons une tonne de jointures à ce sujet et c'est une sorte d'institutionnel que nous utilisons pour regrouper. Je teste une clé alternative mais pour l'instant c'est ce que je dois utiliser.
JNK