J'ai besoin de mettre à jour 100 millions d'enregistrements dans une seule table, en effet, normalisant la table en remplaçant la valeur varchar d'une colonne par un simple ID. (Je dis «remplacer» mais j'écris vraiment l'ID dans une autre colonne.)
Ce que j'essaie de réaliser, c'est de normaliser l'ensemble de données. Les données non encore normalisées n'ont pas d'indexation. Ma pensée était que je ne construirais pas d'index sur les valeurs brutes, en attendant, au lieu d'indexer les clés étrangères qui remplaceraient les valeurs varchar par des valeurs tinyint une fois la mise à jour terminée.
UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
Contexte
- à l'aide de MSSQL 2008 R2 sur Server 2008 R2
- le serveur a 8 Go de RAM
- le serveur a un RAID10, 7200 RPM SATA (pas génial, je sais, en production, cela ne lira que les données et non les données; plus la récente pénurie HD a rendu cela nécessaire pour le coût)
- le serveur a un processeur Xeon quadricœur double
- la machine ne fait rien d'autre (actuellement dédiée au développement, seulement ce processus)
- la journalisation simple est activée (? - mais est-elle toujours enregistrée pour pouvoir être annulée?)
- notez que la requête fait référence à deux bases de données différentes, pour ce que cela vaut
- la "largeur" d'un enregistrement dans le tableau mis à jour est de 455 octets
Ressources pendant l'exécution
- la RAM physique est au maximum
- les E / S de disque sont au maximum
- Le CPU ne fait pratiquement rien (le point d'étranglement est les E / S)
- le temps d'exécution a été de 14 heures et ça compte!
Je soupçonne quelques choses comme j'ai besoin d'un index sur les données brutes, même si je vais supprimer la colonne (AutoClassName) après les mises à jour de normalisation. Je me demande également si je devrais simplement parcourir le tableau un enregistrement à la fois au lieu de JOIN, ce qui semblait ridicule au moment où j'ai commencé cela, mais maintenant il semble que cela aurait été plus rapide.
Comment dois-je changer ma méthodologie pour mes mises à jour de normalisation restantes (similaires à celle-ci) plus rapidement?
la source
TOP
clause. Ce serait mon approche.Je prendrais une approche différente.
Au lieu de mettre à jour les tables existantes, créez simplement une nouvelle table contenant ce dont vous avez besoin.
Ce sera certainement plus rapide:
Tel qu'il est actuellement écrit, de nombreuses opérations logiques se produisent:
la source
Faire une boucle dans le tableau une ligne à la fois, ne sera pas plus rapide!
Comme suspecté et confirmé par vous, cela sera lié aux E / S - ayant un disque, les lectures, les écritures, les journaux de transactions et (tout) l'espace de travail temporaire seront tous en concurrence pour les mêmes E / S.
Une récupération simple enregistrera toujours les transactions, mais le journal sera effacé par un point de contrôle. Il est possible que la taille initiale du journal et les paramètres de croissance automatique entraînent un ralentissement des E / S - le journal des transactions devra augmenter pour s'adapter aux modifications.
Avez-vous essayé d'indexer le champ AutoClassName? Combien de valeurs AutoClass différentes existe-t-il?
Vous devrez peut-être regrouper les mises à jour, en fonction des limites de vos E / S. Alors mettez à jour 1 million, checkpoint, répétez ....
la source
Créez des index pour les champs de jonction.
Vous pouvez toujours supprimer les index lorsque vous avez terminé.
Je serais très surpris si les index n'amélioraient pas significativement les performances de la mise à jour.
la source
Exportez comme vous le souhaitez, créez une nouvelle table et réimportez. En prime, vous auriez une copie des données en tant que sauvegarde, si des miracles se produisaient.
la source