Archivez tout sauf une période continue de 13 mois à partir d'un groupe de grandes tables. Les données archivées doivent être stockées dans une autre base de données.
La table "archive" aura environ 1,1 milliard de lignes, la table "live" environ 400 millions. Évidemment, la table d'archives augmentera avec le temps, mais je m'attends à ce que la table en direct augmente également assez rapidement. Disons 50% au moins au cours des deux prochaines années.
J'avais pensé aux bases de données extensibles Azure, mais malheureusement, nous sommes à 2008 R2 et nous y resterons probablement un certain temps.
Problème: J'essaie de déplacer les données dans les tables partitionnées initiales (en fait, je fais encore une preuve de concept dessus). J'essaie d'utiliser TF 610 (selon le Data Loading Performance Guide ) et un INSERT...SELECT
instruction pour déplacer les données initialement en pensant qu'elles seraient enregistrées de façon minimale. Malheureusement, chaque fois que j'essaie, il est entièrement enregistré.
À ce stade, je pense que mon meilleur pari pourrait être de déplacer les données à l'aide d'un package SSIS. J'essaie d'éviter cela car je travaille avec 200 tables et tout ce que je peux faire par script, je peux facilement le générer et l'exécuter.
Y a-t-il quelque chose qui me manque dans mon plan général, et SSIS est-il mon meilleur pari pour déplacer les données rapidement et avec une utilisation minimale du journal (problèmes d'espace)?
-- Existing structure
USE [Audit]
GO
CREATE TABLE [dbo].[AuditTable](
[Col1] [bigint] NULL,
[Col2] [int] NULL,
[Col3] [int] NULL,
[Col4] [int] NULL,
[Col5] [int] NULL,
[Col6] [money] NULL,
[Modified] [datetime] NULL,
[ModifiedBy] [varchar](50) NULL,
[ModifiedType] [char](1) NULL
);
-- ~1.4 bill rows, ~20% in the last year
CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
( [Modified] ASC )
GO
-- New DB & Code
USE Audit_New
GO
CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201',
'20160101', '20160201', '20160301', '20160401', '20160501', '20160601',
'20160701')
CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );
CREATE TABLE [dbo].[AuditTable](
[Col1] [bigint] NULL,
[Col2] [int] NULL,
[Col3] [int] NULL,
[Col4] [int] NULL,
[Col5] [int] NULL,
[Col6] [money] NULL,
[Modified] [datetime] NULL,
[ModifiedBy] [varchar](50) NULL,
[ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO
CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
[Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO
CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
[Col1] ASC,
[Col2] ASC,
[Col3] ASC,
[Col4] ASC,
[Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO
Déplacer le code
USE Audit_New
GO
DBCC TRACEON(610);
INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified
J'ai trouvé le Data Loading Performance Guide , auquel vous faites référence, comme une ressource extrêmement précieuse. Cependant, il n'est pas non plus complet à 100%, et je soupçonne que la grille est déjà suffisamment complexe pour que l'auteur n'ait pas ajouté de colonne Table Partitioning
pour éliminer les différences de comportement selon que la table recevant les insertions est partitionnée. Comme nous le verrons plus loin, le fait que la table est déjà partitionnée semble inhiber la journalisation minimale.
Sur la base des recommandations du Guide de performances de chargement de données (y compris la section "Chargement en bloc d'une table partitionnée") ainsi que d'une vaste expérience du chargement de tables partitionnées avec des dizaines de milliards de lignes, voici l'approche que je recommanderais:
Les différences par rapport à votre approche d'origine:
TABLOCK
un mois à la fois, en utilisant la commutation de partition pour placer les données dans la table partitionnée.DELETE
pour effacer l'ancienne table sera entièrement enregistré. Vous pouvez peut-être TRUNCATE
ou supprimer la table et créer une nouvelle table d'archive.Afin de comparer les approches dans un délai raisonnable sur ma machine, j'ai utilisé un 100MM row
jeu de données de test que j'ai généré et qui suit votre schéma.
Comme vous pouvez le voir dans les résultats ci-dessous, il y a une augmentation importante des performances et une réduction des écritures de journal en chargeant les données dans un tas à l'aide de l'indicateur TABLOCK
. Il y a un avantage supplémentaire si cela se fait une partition à la fois. Il convient également de noter que la méthode une partition à la fois peut facilement être parallélisée davantage si vous exécutez plusieurs partitions à la fois. Selon votre matériel, cela pourrait donner un coup de pouce Nice; nous chargeons généralement au moins quatre partitions à la fois sur du matériel de classe serveur.
Voici le script de test complet .
Tous ces résultats dépendent dans une certaine mesure de votre matériel. Cependant, mes tests ont été effectués sur un ordinateur portable quad-core standard avec lecteur de disque rotatif. Il est probable que les chargements de données devraient être beaucoup plus rapides si vous utilisez un serveur décent qui n'a pas beaucoup d'autres charges au moment où vous effectuez ce processus.
Par exemple, j'ai exécuté l'approche recommandée sur un serveur de développement réel (Dell R720) et j'ai constaté une réduction à 76 seconds
(de 156 seconds
Sur mon ordinateur portable). Fait intéressant, l'approche originale d'insertion dans une table partitionnée n'a pas connu la même amélioration et a tout de même pris un peu plus de 12 minutes
sur le serveur de développement. Vraisemblablement, c'est parce que ce modèle produit un plan d'exécution en série, et un seul processeur sur mon ordinateur portable peut correspondre à un seul processeur sur le serveur de développement.
Cela peut être un bon candidat pour Biml. Une approche consisterait à créer un modèle réutilisable qui migrerait les données d'une seule table dans de petites plages de dates avec un conteneur For Each. Le Biml parcourrait votre collection de tables pour créer des packages identiques pour chaque table éligible. Andy Leonard a une intro dans son Stairway Series .
Peut-être qu'au lieu de créer la nouvelle base de données, restaurez la vraie base de données dans une nouvelle base de données et supprimez les données les plus récentes de 12 à 13 mois. Ensuite, dans votre vraie base de données, supprimez les données qui ne sont pas contenues dans la zone d'archivage que vous venez de créer. Si les suppressions importantes sont un problème, vous pouvez peut-être simplement supprimer des ensembles de 10 Ko ou plus par le biais d'un script pour le faire.
Vos tâches de partitionnement ne semblent pas interférer et semblent applicables à l'une ou l'autre base de données après vos suppressions.