À quel moment dois-je diviser ou partitionner une table très grande mais simple


8

Notre site contient des tableaux de statistiques importants mais simples (INT, INT, DATE). Chaque table a jusqu'à 300 000 000 lignes et s'agrandit chaque jour.

L'hébergeur a suggéré que nous divisions ou partitionnions les tables, et j'ai vu cette recommandation ailleurs à plusieurs reprises.

Toutefois...

J'ai du mal à concilier ce conseil avec la capacité maximale indiquée pour SQL Server - une taille de base de données de 524 272 téraoctets, avec des lignes de table limitées uniquement par le "stockage disponible".

Sur la base de ces chiffres, le tableau décrit ci-dessus pourrait facilement avoir des centillions de rangées (10 à la puissance de 303).

Ah ha vous pourriez dire, il y a une différence entre CAPACITÉ et PERFORMANCE.

Mais dans pratiquement toutes les questions sur les performances de SQL Server, la réponse est "Cela dépend ... de la conception des tables et de la conception des requêtes".

C'est pourquoi je pose cette question. La conception de la table ne pourrait pas être beaucoup plus simple. Les requêtes qui sont de simples opérations de comptage (*) basées sur un champ ID indexé ne le pouvaient pas non plus.


Le partitionnement des tables est quelque chose que vous planifiez dans la conception de votre base de données, avant d'écrire de préférence les données. Il est beaucoup plus difficile et fastidieux de le faire après coup.

1
Cela dépend davantage de votre scénario: les performances sont-elles bonnes? Pouvez-vous archiver certaines des données? Les tables sont-elles assez grandes pour sauvegarder / restaurer efficacement? Sont-ils compressés? Il aurait été bon de partitionner dès le premier jour, mais le prochain meilleur jour est aujourd'hui si vous êtes préoccupé par les performances futures si vous souhaitez suivre les meilleures pratiques.
LowlyDBA

2
Je pense qu'avec cette quantité de données, vous aurez besoin de diviser votre base de données au niveau architectural, la base de données OLTP et la base de données OLAP. entrepôt "OLAP". En ce qui concerne la question de savoir quand commencer à partitionner vos tables, consultez cet article de Kendra LittleHow To Decide if You Should Use Table Partitioning
M.Ali

3
Les performances ne sont jamais des réservoirs simplement parce qu'une table est grande. En fait, ce qui est grand pour beaucoup est petit pour certains. Comprenez quelles opérations sont accélérées et lesquelles ralentissent en partitionnant. Le partitionnement n'est pas un interrupteur accéléré. C'est un commutateur généralement plus lent et certaines choses deviennent incroyablement rapides.
usr

4
Je recommande fortement la vidéo de formation MCM sur le partitionnement par Kimberly Tripp.
Paul White 9

Réponses:


10

Il y a une raison pour laquelle le conseil général est que cela dépend de la conception de la table et des requêtes. Ma réponse à votre autre article sur Stack Exchange en dit long. Dire "des requêtes qui sont de simples opérations de comptage (*) basées sur un champ ID indexé" ne donne pas beaucoup d'informations car il ne dit rien de la cardinalité de l'ensemble de lignes considéré. Les mesures que vous pouvez prendre pour atténuer les problèmes (tels qu'ils sont perçus actuellement) sont les suivantes:

  1. Partitionnement. Plus précisément, vos données semblent être des données de type journalisation. Je suppose que vous voulez obtenir des statistiques par unité de temps (par exemple, "widgets par jour" ou "whozits par heure"). Partitionnez selon votre quantum (c'est-à-dire jours ou heures dans les exemples précédents) et déplacez occasionnellement des partitions vers des groupes de fichiers en lecture seule

  2. Sur une note connexe, si les données sont en écriture unique, envisagez de pré-agréger les données une fois que la période n'est plus active. Autrement dit, pourquoi dois-je continuer à compter le nombre d'événements qui se sont produits par jour il y a trois ans si ces données ne changeront jamais? Une fois la journée terminée, comptez tout ce jour-là, stockez-le ailleurs et ne le comptez plus jamais. En fait, si vous n'avez jamais besoin des données détaillées (c'est-à-dire que vous ne faites que des agrégations par rapport à elles), envisagez de les supprimer après les avoir comptées. Si vous implémentez cette idée, vous pouvez devenir encore plus intelligent avec des index filtrés qui ne couvrent que la période "active", ce qui rendra vos requêtes plus rapides car ils ne couvriront pas la grande majorité de vos données

Mais, comme le suggère mon conseil dans l'autre post, la seule façon de savoir avec certitude est de le charger avec une quantité raisonnable de données et de l'essayer. Tout ce que nous pouvons faire ici, c'est dire ce qui fonctionnera probablement dans le cas général. Sans les spécificités de votre matériel, de vos données et de vos requêtes, tout ce que nous pouvons faire est de deviner. Et, vous constaterez peut-être qu'une fois que vous avez exécuté le test, je propose que la réponse soit «il n'y a rien à faire» car cela fonctionne très bien tel quel.


Merci Ben. Je commence à comprendre qu'il y a plus de variables en jeu que je ne le pensais au départ. Et j'accepte que, pratiquement, «essayer et voir» est l'approche la plus sensée. Mais comme SQL Server est essentiellement un programme (quoique très compliqué), une partie de moi est frustrée par ce manque de prévisibilité.
Martin Hansen Lennox

1
@MartinHansenLennox et Ben: Je suis tout à fait d'accord avec l'approche "essayez-le" plutôt que d'écouter simplement des conseils ou des spéculations personnelles. Mais, je recommanderais d'énoncer plus explicitement dans ce paragraphe ce que cela signifie vraiment de l' essayer. C'est plus que simplement le charger et exécuter des requêtes. Les tests doivent inclure l'ajout incrémentiel de données pour voir si / comment les choses changent à mesure que les statistiques changent et que les index sont fragmentés, etc. Et essayez de sauvegarder, de restaurer, de reconstruire des index, etc. obtenir une mise à jour complète de l'état lors de la reconstruction.
Solomon Rutzky

@MartinHansenLennox: Vous avez raison d'être frustré par l'approche "essayez-le et voyez". SQL Server est très prévisible et il est au moins en théorie possible d'analyser le problème avant de l'essayer. Cependant, la quantité de connaissances de base requises pour le faire rend souvent cela difficile.
Thomas Kejser

7

Je vais adopter une approche différente et noter que le partitionnement ( dans SQL Server ) est principalement une fonctionnalité de gestion des données, les performances des requêtes étant un résultat secondaire possible , selon la façon dont vous les gérez . 1

Comme indiqué dans l'article lié, le principal avantage du partitionnement est que vous pouvez déplacer rapidement des données à l'aide de la commutation de partition . Par exemple, vous pouvez archiver des données "plus froides" pour un stockage plus lent et conserver vos données "chaudes" sur un stockage rapide. À intervalles réguliers, vous pouvez archiver rapidement des données en les déplaçant sur des partitions d'archivage sans avoir à passer par le processus d'attente d'un ETL pour effectuer le transfert. Comme indiqué dans l'un des premiers commentaires de votre question, cependant, cela nécessitera une réflexion et une planification minutieuses avant de le mettre en œuvre. En outre, selon l'édition de SQL Server que vous utilisez (Enterprise), vous pouvez tirer parti de la compression des données pour compresser des partitions individuelles.

En ce qui concerne les performances, vous pouvez changer l'escalade des verrous en AUTO(par défaut TABLE) comme suit :

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO

De plus, vous pourriez obtenir l'élimination de la partition, mais vos modèles de requête devraient correspondre à un modèle très spécifique et reproductible au sein de votre système - la clé de partitionnement et la clé de clustering et toutes les clés uniques deviennent interconnectées et très importantes . Si cet équilibre n'est pas traité reconnu et conçu autour, vous vous retrouvez avec des cauchemars de performance.

Avec l'avènement de SQL Server 2014, vous pouvez également tirer parti des statistiques incrémentielles, ce qui est très pratique si vous surveillez et mettez à jour / créez proactivement des statistiques sur de grandes tables.

Alors, à quel moment une table doit-elle être partitionnée? Cela dépend de la charge de travail de votre requête, du profil de vos données, mais surtout, cela dépend des fonctionnalités de gestion du partitionnement que vous devez absolument utiliser. Le partitionnement n'est pas destiné aux performances des requêtes, il est principalement destiné à la gestion et à l'administration des données.


2
"Le partitionnement n'est pas pour la performance des requêtes, c'est principalement pour la gestion et l'administration des données" - semble évident quand vous le dites, mais je ne l'avais jamais tout à fait compris auparavant. Great links btw, thanks
Martin Hansen Lennox

Merci d'avoir mentionné que cette fonctionnalité est principalement destinée à la gestion et non aux performances. Je vois rarement cela mentionné et c'est assez frustrant.
Solomon Rutzky

1
@MartinHansenLennox: Le partitionnement est également très utile pour les performances. Par exemple, si vous utilisez des astuces de partitionnement de hachage et pour des valeurs qui ont une faible cardinalité.
Thomas Kejser

7

Avant de décider de la taille de la partition, veuillez considérer les implications du partitionnement sur le plan de requête. Du point de vue purement de la performance, les partitions servent de forme d'index à grain grossier. Cela peut fournir des performances supplémentaires, mais c'est également une source de régressions de performances, surtout si la clé de partition n'apparaît pas dans toutes les requêtes. À partir d'ici, je suppose que vous avez déjà fait ces devoirs (comme il semble que vous l'ayez fait).

Une bonne règle de base pour la taille d'une partition que vous voulez est la suivante: environ la moitié de la taille de la DRAM que vous avez sur la boîte. La raison de cette recommandation est:

  1. Vous pouvez reconstruire les index sur la partition sans déborder tempdb. c'est BEAUCOUP plus rapide que si vous utilisez l'accès au disque (même avec SSD).
  2. Pendant que vous effectuez cette reconstruction, vous pouvez toujours conserver une partition entière (généralement la plus récente) dans la DRAM pour conserver le bon fonctionnement de votre requête.

En d'autres termes, vous souhaitez disposer de suffisamment de DRAM pour contenir deux partitions et la taille de partition que vous souhaitez dépend de la machine sur laquelle vous exécutez. Les machines plus grandes peuvent gérer confortablement de plus grandes partitions.

Notez que ce guide fournit également une taille minimale pour tempdb: Au moins la taille de votre plus grande partition (vous pouvez donc y déverser la génération d'index s'il n'y a pas assez de DRAM lorsque vous reconstruisez un index).

Vous pouvez envisager des tailles de partition plus petites que cela, mais si vous le faites, cela est généralement destiné à l'optimisation des performances et non à la prise en charge de la gestion des données.

Il existe une tonne d'autres astuces que vous pouvez jouer avec les partitions. Par exemple, la compression, l'agrégation ou l'utilisation du facteur de remplissage 100 sur des partitions en lecture seule. Mais le principe de base est toujours: Essayez de garder chaque bloc de données que vous gérez plus petit que la DRAM.

PS: Heureux de voir que vous ne prenez pas "ça dépend" comme réponse, demandez toujours une méthode pour obtenir la réponse.


Merci Thomas, bons conseils, appréciez particulièrement les explications sur le dimensionnement des partitions.
Martin Hansen Lennox

7

Le partitionnement de table, comme plusieurs autres fonctionnalités, est assez souvent (ou peut-être même le plus souvent?) Utilisé de manière inappropriée. Toutes les mises en garde que je donnerais ont été bien énoncées dans la réponse de @ swasheck .

De plus, une alternative à considérer est les vues partitionnées. C'est une façon de conserver des tables complètement séparées mais de les lier ensemble via UNION ALL dans une vue. Chaque table nécessite une CONTROLE DE VERIFICATION qui applique la plage de données que contient chaque table. L'optimiseur connaît cette construction et ne doit accéder qu'aux tables sous-jacentes requises par une requête à l'aide de la vue (je ne me souviens pas de toutes les exigences pour que ce travail soit comme prévu, veuillez donc voir le lien CREATE VIEW en bas, mais Je l'ai installé avant et il n'a pas été difficile de le faire fonctionner comme prévu).

Il y a certainement quelques restrictions, et un inconvénient principal est qu'il est moins transparent par rapport au partitionnement de table. Cependant, un avantage principal est que ce sont des tables distinctes, et donc les statistiques sont complètement séparées, alors qu'avec une table partitionnée, elles concernent la table entière (même si, à partir de SQL Server 2014, vous pouvez mettre à jour les statistiques par partition).

Si vous n'utilisez pas la commutation des partitions vers l'intérieur et vers l'extérieur, vous devriez envisager cette option. Surtout si les anciennes données ne changent pas beaucoup car les tables contenant les anciennes données n'ont pas besoin que leurs index / statistiques soient mis à jour presque aussi souvent (ou peut-être jamais si ces données ne changent jamais).

Un autre inconvénient du partitionnement de table qui passe trop souvent inaperçu / inaperçu est qu'à partir de SQL Server 2012, vous n'obtenez plus de STATISTIQUES DE MISE À JOUR «gratuites» AVEC FULLSCAN lors de la reconstruction des index partitionnés. Vous obtenez toujours ces statistiques de mise à jour avec une reconstruction sur les index non partitionnés, ce que seraient les index des tables dans une vue partitionnée :).

Pour plus d'informations sur les vues partitionnées, consultez la page MSDN pour CREATE VIEW et recherchez la section sur les "vues partitionnées" sous "Remarques".


2
Grand point sur la mise à jour des statistiques. Les vues indexées contournent de nombreux problèmes de partitionnement si vous pouvez gérer l'impact de l'optimiseur.
Thomas Kejser
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.