SQL Server 2014 CTP1 introduit des extensions aux options de fonctionnement en ligne qui seront une bonne nouvelle pour les entreprises hébergeant de très grandes bases de données qui nécessitent peu ou pas de temps d'arrêt.
Pour définir le contexte, imaginez que vous utilisez SQL Server 2012 Enterprise Edition pour les fonctionnalités de gestion d'index en ligne et de partitionnement d'index et que vous tentez la reconstruction d'index suivante sur une table partitionnée :
ALTER INDEX [PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber] ON [dbo].[FactInternetSales] REBUILD PARTITION = ALL WITH (ONLINE= ON);
En testant cela dans SQL Server 2012, nous sommes en mesure de reconstruire toutes les partitions en ligne sans erreur. Mais que se passe-t-il si nous voulons spécifier une partition spécifique au lieu de toutes les partitions ?
ALTER INDEX [PK_FactInternetSales_SalesOrderNumber_SalesOrderLineNumber] ON [dbo].[FactInternetSales] REBUILD PARTITION = 1 WITH (ONLINE= ON);
En tentant cela dans SQL Server 2012 ou une version antérieure, vous verrez le message d'erreur suivant :
Msg 155, Niveau 15, État 1, Ligne 4'ONLINE' n'est pas une option ALTER INDEX REBUILD PARTITION reconnue.
Mais à partir de SQL Server 2014 (à partir de CTP1), les opérations d'index de partition unique en ligne sont désormais prises en charge. Et c'est certainement un gros problème pour les très grands scénarios de maintenance de table où vous préféreriez, ou même devez diviser votre maintenance globale en plus petits morceaux sur une période de temps. Vous pouvez également effectuer une maintenance au niveau des partitions uniquement pour les partitions qui en ont réellement besoin, par exemple, les partitions qui dépassent en fait un niveau de fragmentation spécifique.
Pour tester cette fonctionnalité SQL Server 2014 CTP1, j'ai utilisé AdventureWorksDW2012 avec une version de FactInternetSales contenant 61 847 552 lignes et partitionnée par la colonne ShipDate.
Reconstruire toutes les partitions en ligne pour la table en utilisant PARTITION = ALL
dans mon environnement de test a pris 3 minutes et 23 secondes. En ce qui concerne la durée globale, mes tests concernaient des index qui n'étaient pas si fragmentés que ça, donc la durée de 3 minutes et 23 secondes représente une durée moyenne sur quelques tests. Gardez également à l'esprit que je n'avais pas de charges de travail concurrentes en cours d'exécution à l'époque, de sorte que la reconstruction en ligne se produit sans avoir à rivaliser avec d'autres charges de travail importantes par rapport à l'index en question.
La forme du plan d'exécution de la requête pour la reconstruction de l'index en ligne à l'aide de PARTITION = ALL
était la suivante :
Plan d'exécution pour la reconstruction en ligne de toutes les partitions
Notez que les opérations sont activées en parallèle, à l'exception de l'opérateur Constant Scan. Dans le plan d'exécution de la requête, vous pouvez voir 39 lignes dans la référence externe Constant Scan qui sont transmises à l'opérateur Distribute Streams, puis pilotent la boucle imbriquée.
La signification des 39 rangées ? La requête suivante valide le nombre maximal de partitions à partir de sys.dm_db_partition_stats
. Pour mon environnement de test, le résultat était de 39 pour le nombre maximal de partitions, ce qui correspond à ce que j'ai vu pour les lignes réelles de Constant Scan :
SELECT MAX([partition_number]) AS [max_partition_number] FROM [sys].[dm_db_partition_stats] WHERE [object_id] = OBJECT_ID('FactInternetSales');
Maintenant, vous remarquerez également l'opérateur d'insertion d'index en ligne dans le plan précédent. Suppression du ONLINE = ON
option de mon ALTER INDEX REBUILD
(ce qui en fait une opération hors ligne), et en gardant la PARTITION = ALL
option, le seul changement était d'avoir un opérateur "Insert d'index" au lieu d'un "Insert d'index en ligne" dans le plan d'exécution de la requête - et aussi une réduction de la durée, où mon test a montré une durée d'exécution de 1 minute et 9 secondes par rapport à l'en ligne 3 minutes et 23 secondes.
J'ai ensuite testé une reconstruction en ligne d'une partition avec 5 678 080 lignes à la place (rappelez-vous que le nombre total de lignes de table est de 61 847 552 lignes). Pour ce test, la durée globale a duré exactement 1 minute et avait la forme de plan d'exécution de requête suivante :
Plan d'exécution pour la reconstruction en ligne d'une seule partition
Le premier constat est qu'il s'agit d'un plan en série. Notez également que j'ai dit que j'avais choisi une partition parmi les 39 d'origine, bien que cette partition particulière représente environ 9 % des lignes de la table dans son ensemble. Notez également que le balayage constant affiche 1 ligne au lieu de 39, comme je m'y attendais.
Qu'en est-il de la durée d'une seule partition, reconstruction hors ligne ? Dans mon environnement de test, cela a pris 11 secondes par rapport à la reconstruction en ligne 1 minute. La forme du plan d'exécution de la requête pour la reconstruction hors ligne d'une seule partition était la suivante :
Plan d'exécution pour la reconstruction hors ligne d'une seule partition
Notez qu'il n'y a pas de processus d'analyse constante ou de boucles imbriquées associées et notez également que ce plan contient désormais des opérateurs parallèles par rapport au plan en série précédent, même s'ils effectuent tous les deux une analyse d'index clusterisée pour 5 678 080 lignes. De plus, une recherche par mot-clé de "partition" dans le texte du plan XML pour l'opération d'index parallèle hors ligne à partition unique n'a donné aucune correspondance - par rapport au plan série, opération d'index de partition unique en ligne qui avait Partitioned ="true" pour le Opérateurs physiques Clustered Index Scan et Online Index Insert.
Retour à l'exploration principale…
Puis-je choisir quelques partitions, mais pas toutes, en une seule exécution ? Malheureusement non.
Le ALTER INDEX
et ALTER TABLE
les commandes ont le PARTITION = ALL
argument puis PARTITION = <partition number>
argument, mais pas la possibilité de répertorier plusieurs partitions pour une seule opération de reconstruction. Je ne m'en plains pas trop fort cependant, car je suis heureux d'avoir la possibilité de reconstruire une seule partition en ligne et ce n'est pas très compliqué d'exécuter l'opération une fois pour chaque reconstruction, mais l'impact cumulatif sur la durée était quelque chose Je voulais explorer davantage.
Combien de temps faudrait-il pour reconstruire les 39 partitions séparément et en ligne par rapport à la PARTITION = ALL
durée de 3 minutes et 23 secondes ?
Nous savons que l'un des avantages des reconstructions en ligne est la possibilité d'accéder à la table ou à l'index associé pendant l'opération d'indexation. Mais en échange de cette opération en ligne, nous perdrons l'avantage des performances de la reconstruction par rapport à une reconstruction hors ligne. Et ce que je voulais savoir ensuite, c'était comment une reconstruction en ligne de partition une par une fonctionnerait par rapport à la PARTITION = ALL
alternative.
En exécutant 39 opérations de reconstruction distinctes (une reconstruction pour chaque partition unique), la durée totale d'exécution était de 9 minutes et 54 secondes par rapport à la PARTITION = ALL
qui a pris 3 minutes et 23 secondes, il est donc clair que l'approche fragmentaire n'est pas aussi rapide qu'une reconstruction en ligne de toutes les partitions dans une seule instruction. Alors que j'étais capable de faire une partition à la fois, l'avantage primordial est la possibilité de séparer nos activités de maintenance au fil du temps et de garder l'accès aux objets pendant leur reconstruction, mais si vous recherchez une reconstruction plus courte fenêtre, les options hors ligne sont toujours les plus rapides, suivies par en ligne pour PARTITION = ALL
puis en dernier lieu, en faisant une partition à la fois.
Le tableau suivant récapitule les comparaisons de durée - et encore une fois, ces tests étaient basés sur SQL Server 2014 CTP1 et une taille de table très spécifique et une configuration d'invité de VM, donc faites plus attention aux durées relatives des tests plutôt qu'aux durées elles-mêmes :
Description du test | Durée |
---|---|
Reconstruction hors ligne de toutes les partitions | 1:09 |
Reconstruction en ligne de toutes les partitions | 3:23 |
Reconstruction en ligne d'une partition | 1:00 |
Reconstruction hors ligne d'une partition | 0:11 |
Reconstruction en ligne de toutes les partitions, une partition à la fois | 9:54 |
Il y a maintenant d'autres aspects à explorer sur ce sujet également. Ce n'est pas parce qu'une opération est en ligne qu'il n'y a pas quelques instants (ou plus) où des verrous sont toujours maintenus sur l'objet ciblé. Les opérations d'index ont toujours un comportement de verrouillage pour les opérations en ligne - et SQL Server 2014 a également fourni des options pour cela que j'explorerai dans un article séparé.