L'insertion massive de données (bulk insert) est une tâche typique lors de la migration, de l'importation ou du remplissage de grandes tables. L'efficacité de cette opération dépend de plusieurs facteurs :
BULK INSERT ou COPY (PostgreSQL) — ils fonctionnent plus rapidement que les INSERT traditionnels en boucle.BULK INSERT my_table FROM 'C:\data\bulkdata.csv' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = ' ', BATCHSIZE = 5000, TABLOCK );
TABLOCKréduit les conflits de verrouillage lors des insertions massives.
Question : Peut-on à tout moment désactiver et reconstruire des index pour accélérer l'insertion massive, si la table participe à des transactions ?
Réponse : Non, si la table participe à des transactions actives, la désactivation ou la reconstruction des index peut entraîner des verrouillages, une violation de l'intégrité des données ou même une perte de données si la transaction est annulée. Cette opération doit être effectuée uniquement en dehors des transactions, ou planifiée à l'avance dans des fenêtres de maintenance.
-- Incorrect : BEGIN TRAN; ALTER INDEX ALL ON my_table DISABLE; -- ... bulk insert ... ALTER INDEX ALL ON my_table REBUILD; COMMIT;
Une telle désactivation est inacceptable dans de longues transactions !
Histoire 1 : Dans un projet, des insertions massives parallèles dans une table avec plusieurs index uniques ont conduit à des blocages fréquents et à une forte chute des performances. La solution a été la désactivation temporaire des index non clés pendant la période d'importation et la réduction de la taille des opérations par lots.
Histoire 2 : Les développeurs ont oublié de désactiver le contrôle des clés étrangères pendant la période de chargement des données, et chaque insertion vérifiait l'existence d'enregistrements associés dans d'autres grandes tables. Cela a augmenté le temps de chargement de 40 minutes à 9 heures. Après avoir désactivé les contraintes, l'insertion a pris 12 minutes.
Histoire 3 : Tenter d'insérer un grand fichier en une seule requête (sans mise en lot et sans transactions) a entraîné un débordement du journal des transactions (transaction log full) et un arrêt brutal du serveur de base de données. Après être passé à un traitement par lots, le problème a disparu.