Conception de grandes tables SQL

17

J'ai une question générale sur la conception des tables SQL Server 2008. Nous avons actuellement une table de plus de 600 Go et se développe à environ 3 Go par jour. Ce tableau contient les indecies appropriés mais devient un blocage majeur lors de l'exécution de requêtes et uniquement en raison de sa taille. La question est de savoir si je dois diviser la table en plusieurs tables par année et par mois (cela correspondrait à la façon dont les autres départements répartissent leurs grands ensembles de données) ou devrions-nous tirer parti du partitionnement intégré à SQL Server. Il semble que l'utilisation du partitionnement nécessiterait moins de modifications de code. D'après ce que j'ai lu lors du partitionnement, il vous suffit d'interroger une table et le serveur gère comment obtenir les données. Si nous options pour la route à tables multiples, nous devions gérer l'extraction des données de plusieurs tables.

HunterX3
la source
1
Y a-t-il des optimisations à faire: types de données trop larges, index superposés ou inutilisés, etc.?
gbn
Peut-être, je n'ai pas encore regardé au-delà des indécies pour d'autres optimisations. Avez-vous des recommandations?
HunterX3

Réponses:

11

"Ce tableau contient les indecies appropriés mais devient un blocage majeur lors de l'exécution de requêtes"

Le partitionnement seul n'aide pas les performances des requêtes, sauf si SQL Server est en mesure d'éliminer les partitions lors de l'exécution d'une requête. Votre clause WHERE doit correspondre à la façon dont vous partitionnez. Nous n'avons qu'un seul champ à utiliser comme champ de partitionnement, donc si ce champ n'est pas inclus dans votre clause WHERE, vous êtes toujours susceptible d'analyser la table entière malgré les partitions.

"et juste à cause de sa taille."

Le partitionnement peut faciliter certaines opérations de maintenance, mais il y a encore des choses que nous ne pouvons pas faire partition par partition. Si la maintenance de l'index et les mises à jour des statistiques vous posent des problèmes, vous feriez mieux de diviser la conception en une table d'archives et une table mise à jour en direct. Lorsque vous devez déplacer périodiquement des données de la table en direct vers la table d'archivage, vous le faites, reconstruisez les index avec un facteur de remplissage de 100%, mettez à jour les statistiques avec une analyse complète, puis définissez son groupe de fichiers en lecture seule. Le partitionnement peut aider au chargement des tables d'archives, mais pas le partitionnement de la table active. (Je jette ici plusieurs concepts avancés comme si c'était rapide et simple, mais je ne fais qu'esquisser un arrière-plan ici.)

"Il semble que l'utilisation du partitionnement nécessiterait moins de modifications de code."

Sorta un peu - cela ressemble à cela à première vue, mais plus vous y entrez, vous avez des options comme les vues partitionnées. Vous pouvez renommer la table existante, mettre une vue à sa place, puis vous pouvez apporter vos propres modifications aux tables sous-jacentes (et ajouter plusieurs tables) sans changer votre application.

J'ai écrit plus sur les pièges du partitionnement ici:

http://www.brentozar.com/archive/2008/06/sql-server-partitioning-not-the-answer-to-everything/

Brent Ozar
la source
3
La citation préférée de cet article est très certainement "Les fonctions et les schémas de partition sont faciles à concevoir de manière incorrecte."
Mark Storey-Smith,
7

Le partitionnement isolé peut être suffisant, mais vous pouvez obtenir de meilleurs résultats en combinant avec des vues partitionnées et plusieurs tables. Cela dépend beaucoup du modèle d'interrogation et de croissance.

La limitation actuelle du partitionnement est que les statistiques de colonne ne sont conservées qu'au niveau d'une table plutôt qu'au niveau de la partition. Si vous avez un modèle d'interrogation qui bénéficierait de statistiques plus précises, la combinaison du partitionnement de table avec des vues partitionnées pourrait apporter des avantages significatifs en termes de performances.

Lorsque la nature de vos données varie d'un mois à l'autre, d'une année à l'autre, les vues partitionnées peuvent également vous aider. Imaginez un détaillant qui change continuellement ses gammes de produits, de sorte qu'il y a peu de cohérence dans les gammes Product.ProductId utilisées d'une année à l'autre. Avec une seule table order / orderdetail et donc un seul histogramme de statistiques, les statistiques offriront peu à l'optimiseur de requêtes. Une table par an (Order_2010, Order_2011, OrderLine_2010, OrderLine_2011) partitionnée par mois et combinée avec des vues partitionnées (Order, OrderLine) fournira des statistiques plus granulaires et potentiellement utiles à l'optimiseur.

Vous pouvez introduire le partitionnement de table avec relativement peu d'efforts, alors commencez par là, mesurez l'impact et évaluez plus tard si les vues partitionnées valent l'effort supplémentaire.

Kimberly Tripp a publié de nombreux conseils et livres blancs sur le partitionnement qui sont généralement considérés comme une lecture obligatoire sur le sujet. Kendra Little a également du bon matériel et une liste de référence utile d'autres articles

Les performances sont généralement la première raison pour laquelle les utilisateurs recherchent le partitionnement. Personnellement, je considère les améliorations du temps de récupération comme un avantage égal ou supérieur avec un VLDB. Prenez le temps de comprendre la disponibilité partielle et la restauration fragmentaire avant de commencer car cela peut influencer l'approche que vous adoptez.

Si vous avez le processus non idéal mais pas rare d'envoyer des sauvegardes sur le réseau, vous envisagez peut-être un temps de restauration de 3 heures pour votre 600 Go actuel. Dans un an où vous avez dépassé 1,5 To, vous avez un problème.

Mark Storey-Smith
la source
1
+1 Pour "les statistiques de colonne ne sont conservées qu'à une table", et j'aimerais pouvoir +1 à nouveau pour les liens vers Kimberly et Kendra.
Matt M
1

Comme vous l'avez dit, vous avez deux options ici:

  1. Utiliser plusieurs tables
  2. Utiliser le partitionnement

Avec 1, vous pouvez créer une VUE qui rassemble toutes ces tables et la mettre à jour pour inclure les tables nouvellement créées. Je considère que c'est vraiment un moyen d'émuler le partitionnement. Les avantages de cette méthode incluent le fait de ne pas exiger l'édition Enterprise de SQL Server.

Avec 2, vous pouvez aligner vos index sur vos partitions et aligner vos partitions sur un stockage différent. Une fois que vous avez configuré votre fonction de partition et votre schéma de partition, cela est fait pour vous lorsque vous fractionnez ou fusionnez des partitions. Les avantages de cette méthode incluent le fait de ne pas être obligé de déplacer manuellement les enregistrements vers une nouvelle table. Étant donné que la fonction de partition et le schéma de partition gèrent cela pour vous. De plus, comme vous l'avez dit, peu ou pas de changement de code n'est nécessaire pour accéder aux données.

Si vous avez Enterprise Edition, je donnerais certainement un coup d'oeil au partitionnement. Malgré sa complexité, ce n'est vraiment pas si mal. Sinon, le partitionnement n'est même pas une option pour vous.

Création de tables partitionnées

Modification des tables partitionnées

Conception de partitions pour gérer des sous-ensembles de données

J'espère que cela t'aides,

Mat

Matt M
la source
0

D'après votre question, vous semblez stocker des données historiques (journaux) et votre limitation semble provenir de la vitesse des requêtes, et non des problèmes de salle de stockage. Pour moi, la partition n'aidera pas.

Lorsque vous dites que vous disposez d'index appropriés, cela inclut-il un index sur le champ de date? J'ai eu de bons résultats en utilisant index sur trunc (horodatage, jour) avec Postgres. Vous devez ensuite vous assurer que toutes les requêtes sont sélectionnées la veille de toute autre manipulation. Attention, un horodatage avec un champ de fuseau horaire n'est pas indexable (car il "se déplace" en fonction du fuseau horaire), vous avez donc besoin d'un horodatage "fixe" pour être indexé.

gb.
la source
Nos indécies sont basées sur les champs les plus utilisés. Nous avons 1 cluster et 2 non cluster, les deux semblent fonctionner comme annoncé. Je pense que c'est plus de la taille qui est le problème.
HunterX3