web-dev-qa-db-fra.com

Bonne stratégie pour les grandes tables et l'archivage dans SQL Server 2012

J'ai une table avec environ environ 500 000 rangées par jour en y adressant. La base de données prend en charge un fichier OLTP System. La composition de celui-ci est un peu comme ceci:

create table Stuff 
(StuffID int identity not null primary key,  
ValueA decimal(18,4) not null,   
ValueB decimal(18,4) not null,  
ValueC decimal(18,4) not null,   
ValueD decimal(18,4) not null,  
StuffName varchar(10) not null,   
Created datetime not null default(getdate())  )

J'ai un indice de couverture sur celui-ci en raison du type de requêtes qui l'exécutent.

Généralement, je travaille avec les données de la journée en cours. Très peu de mes questions ciblent la clé primaire. J'avais envisagé de déplacer l'index en cluster de la clé primaire et de la colonne créée (DateTime), car une grande partie de mon interrogation est basée sur cela, et je veux généralement les résultats dans l'ordre chronologique.

J'aimerais tout garder dans une table d'une seule fois parce que d'un point de vue fonctionnel, je n'ai aucune raison de le déplacer, mais je crains que, en n'ayant pas une stratégie d'archive de type, je aura finalement avoir "trop ​​de" rangées dans là. Dans cinq ans, je devrais avoir un milliard d'enregistrements, ce qui n'est peut-être pas une grosse affaire compte tenu de la taille de données relativement faible de ma table.

BOOGLED DOWN: Pour une petite table de tailles de données avec des lignes de 500K, ce qui est une stratégie particulière que je devrais regarder? Vais-je rencontrer un ralentissement général en raison de la taille ou n'y a-t-il vraiment rien à craindre?

1
Eric

Espérons que cette taille vous êtes sur l'édition d'entreprise? Sinon, bonne chance :) (juste blague voir le fond de la réponse)

Si vous êtes sur l'entreprise, je suggérerais de regarder partitionnement. Cela a sauvé mes fesses une heure ou deux lorsque vous traitez avec ce même type de scénario. Créez vos partitions sur le champ Date et vous devrez déterminer le mieux à quel point vous voulez ces partitions. J'ai fait une partition par jour et j'ai également fait une partition par mois. Tout dépend de la quantité d'histoire dont vous avez besoin (rappelez-vous que vous obtenez seulement une limite fixe sur le nombre de partitions par table).

Si vous limitez la partition à une journée et que vos requêtes ne sont que pour une journée spécifique, l'optimiseur doit pouvoir utiliser l'élimination de la partition pour choisir uniquement les partitions dont il a besoin pour votre requête. De plus, lorsque le temps vient de purger d'anciennes données après plusieurs années, la cloison coulissante le rend vraiment facile/rapide à purger des données (plutôt que de supprimer des déclarations). Même chose qui vient d'archiver que de vieilles données à une autre table complètement.

Idées non-entreprises:
[.____] Parler d'archivage à une autre table, cela aiderait également et non à exiger l'entreprise. Si cette table n'est utilisée que pour des lectures pour quelque chose de plus d'âge d'un mois ou d'un an, vous pouvez:
[.____] 1) Créer une deuxième table nommée Stuff_Archive
[.____] 2) Déplacez tout plus âgé d'un mois ou d'un an (votre préférence)
[.____] 3) Renommez votre table de choses actuelle à Stuff_Current
[.____] 4) Créer une vue Nommé Stuff que les syndicats Stuff_Current et Stuff_Archive. De cette façon, toute application utilisant des trucs sera toujours en mesure de lire les deux. Et vous pouvez changer vos requêtes pour simplement partir de choses.

Une chose à laquelle je pense peut-être peut-être même d'ajouter une contrainte que vous devrez changer à chaque fois que vous déplacez des enregistrements à Stuff_Archive (je n'ai pas testé cela, mais je prévois de l'essayer sur une DB, j'ai actuellement besoin de conserver comme ça ). Cette contrainte serait au domaine de la date afin qu'elle aide l'optimiseur savoir "OK, même si je l'axe sur ces deux tables, vous n'avez même pas besoin de regarder la table A si je demande des dates entre x et y et table B Si je demande des dates entre Y et Z ". Théoriquement, je supposerais que les statistiques de la colonne/index indiqueraient déjà à l'optimiseur qui, mais je me suis toujours demandé (encore une fois, pas eu le temps de tester) si une contrainte aiderait?

Et l'autre idée de non-Enterprise serait de créer un index non clusterné sur le champ de date et mieux mieux (si vous pouvez l'adapter dans une fenêtre de maintenance) un index filtré où DT> = somédate dans le passé et DT <= SO SOMEDATE à l'avenir. De cette façon, toutes les questions que vous écrivez seront en mesure d'utiliser cet index filtré et ne seront que aussi importantes que les données de cette plage de date (plutôt que sur tout ce que vous avez dans votre table en croissance). Dans d'autres mots: Si vous créez un index filtré pendant une semaine, vous ne faites que traiter uniquement des enregistrements de 500k * 7 = 3,5 m plutôt que de 5 milliards d'enregistrements. Il vous suffit de vous assurer de reconstruire cet indice assez souvent pour garder cette fenêtre décrite dans le filtré où des critères dans les délais impartis pour vos requêtes. Donc, si vous pouvez le reconstruire quotidiennement et que vous n'avez besoin que de données d'hier, alors super. Mais si vous ne pouvez le reconstruire que le week-end, vous devrez peut-être vous assurer que les statistiques sont tenues à jour tout au long de la semaine.

3
Chris Woods

Dépend un peu sur les modèles d'accès aux données. Je suppose que c'est écrit de manière séquentielle. Est-ce vrai? Que diriez-vous des lectures? Séquentiel ou aléatoire?

Si tout est séquentiel et que vous avez un tuyau d'E/S robuste, tout ira bien. Si c'est aléatoire ou si vous avez une mauvaise installation d'E/S, vous rencontrez des problèmes sans archiver les données.

Mind, vous n'avez donné aucun détail matériel, donc je fais un vaste nombre d'hypothèses basées sur une expérience de 11 ans VLDB.

0
user41207