Question

J'ai un million de lignes dans une table de base de données. Pour chaque ligne, je dois exécuter un fichier EXE personnalisé, analyser la sortie et mettre à jour une autre table de base de données

Comment puis-je exécuter le traitement de plusieurs lignes en parallèle?

J'ai maintenant une tâche de flux de données simple - > GetData- > Exécuter le script (processus, analyse, sortie) - > Stocker les données Pour 6000 lignes, cela a pris 3 heures. Trop de temps.

Était-ce utile?

La solution

Il existe un seul goulot d'étranglement ici, qui exécute le processus pour chaque ligne. Augmentation de " EngineThreads " n’aiderait pas du tout, car il n’y aura de toute façon qu'un seul thread exécutant ce script particulier. Le temps passé dans d'autres transformations n'a probablement aucune importance. Les processus sont des objets lourds, et en exécuter des milliers ne sera jamais bon marché.

Je peux penser aux idées suivantes pour le rendre meilleur:

1) Le meilleur moyen de résoudre ce problème est de convertir votre fichier EXE personnalisé en un assemblage et de l'appeler à partir de la transformation de script - afin d'éviter la surcharge liée à la création de processus, à l'analyse du résultat, etc.

2) Si vous devez utiliser des processus distincts, vous pouvez essayer de les exécuter en parallèle. Cela aidera si le processus attend la plupart du temps des entrées / sorties (c’est-à-dire qu’il est lié aux E / S). Si les processus sont liés à la mémoire ou au processeur, vous ne gagnerez pas grand chose en les exécutant en parallèle.

2A) Script complexe, package simple.

Pour les exécuter en parallèle, modifiez la méthode ProcessInput dans votre script pour démarrer le processus de manière asynchrone et n'attendez pas l'achèvement du processus. Passez à la ligne suivante et créez le processus suivant. Abonnez-vous pour traiter les sorties et les événements finis afin que vous sachiez quand il est terminé. Limitez le nombre de processus exécutés en parallèle, sinon vous manquerez de mémoire. Attendez que tous les processus soient terminés avant de renvoyer un appel ProcessInput.

2B) Script simple, package complexe.

Conservez le script séquentiel actuel, mais partitionnez les données à l'aide de SSIS. Ajoutez une transformation fractionnée conditionnelle et divisez le flux d'entrée en plusieurs flux, en fonction d'une expression de hachage, afin que chaque sortie reçoive à peu près la même quantité de données. Le nombre de flux est égal au nombre d'instances de processus que vous souhaitez exécuter en parallèle. Ajoutez votre transformation de script à chaque sortie de fractionnement conditionnel. Vous devez maintenant également augmenter les " Threads de moteur " property :) et ces transformations seront exécutées en parallèle. (Remarque: en fonction de la balise, je suppose que vous utilisez SSIS 2008. Vous devrez insérer des transformations Union All supplémentaires pour que cela fonctionne dans SSIS 2005).

Cela devrait améliorer ses performances, mais des millions de processus représentent beaucoup. Vous obtiendrez difficilement de très bonnes performances ici.

Autres conseils

Si vous exécutez ce processus à l'aide du " flux de données " contenant, il y a une propriété dessus " EngineThreads " La valeur par défaut est 5. Vous pouvez lui attribuer un nombre plus élevé, comme 20, ce qui permettra à davantage de threads de traiter ces lignes.

Il s’agit simplement d’une optimisation des performances ou d’une optimisation. Si votre paquet ssis fonctionne toujours très lentement, je voudrais peut-être aborder l’architecture et la conception de votre paquet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top