Peut-être qu'il n'y a pas de réponse simple à cette question, mais je demande au cas où quelqu'un ait, sinon une réponse simple, au moins une perspicacité. P>
J'ai eu plusieurs occasions où je crée une boucle qui traverse de nombreux enregistrements dans une table de base de données effectuant une certaine mise à jour, et où je pouvais légitimement faire un grand commit à la fin ou commettre chaque enregistrement comme je l'ai traitée. . c'est-à-dire commettre une à la fois ne créerait aucune question d'intégrité de données. P>
Y a-t-il un cas clair pour lequel c'est mieux? P>
Qu'est-ce qui l'apporte à l'esprit, c'est que j'avais un tel programme que j'ai récemment passé d'un gros grand engagement à un tas de petits commits car c'était un programme de course assez long - environ 80 minutes - et il a échoué à mi-chemin à travers des mauvaises données. J'ai corrigé le problème et re-couru, mais il devait alors recommencer à partir du début lorsque j'aurais pu simplement traiter les enregistrements précédemment non transformés. p>
J'ai remarqué quand j'ai fait ce changement que le temps d'exécution était à peu près la même chose. p>
3 Réponses :
Je pense que la réponse est que vous avez besoin de retourner tout si on échoue? Si oui, mettez la transaction à l'extérieur, sinon mettez-la à l'intérieur. Bien sûr, je n'écrirais presque jamais une boucle pour faire une mise à jour de toute façon, sauf pour traiter des lots de disques assez volumineux. Si vous effectuez des mises à jour de ligne par ligne, il existe de meilleures méthodes plus performantes. p>
Je ne suis pas sûr de ce que vous entendez par "ne jamais écrire une boucle pour faire une mise à jour de toute façon, sauf pour traiter des lots assez volumineux". Umm, par opposition à quoi? Si je n'avais qu'un seul disque à mettre à jour, bien sûr, je n'aurais pas de boucle.
Et oui, si toute la mise à jour doit être considérée comme une seule transaction que si seule une partie de celle-ci a été effectuée entraînerait des données incohérentes, bien sûr, la validation doit être à l'extérieur. Je pensais aux cas où du point de vue logique, peu importe.
Par opposition à une mise à jour consumée. Si vous avez 100 enregistrements à mettre à jour, ils peuvent être effectués à 99,9% du temps dans une mise à jour sans boucle et devraient être faites de cette façon. Les daatbases ne sont pas optimisées pour les opérations à ligne à ligne.
Suivi très tard: Si vous voulez dire, je pouvais écrire une seule mise à jour, comme "Mettre à jour My_Table Set FOO = FOO * 2 Où Bar = 5", sûr, je n'écrirais pas une centaine de déclarations de mise à jour distinctes. Quand j'ai posté cette question, je pensais que je pensais que cela n'est pas possible, comme si vous mises à jour sur la base de données provenant d'une autre source.
Lorsque vous mettez à jour à partir d'une autre source, il est possible et préférable d'écrire un code à base de réglage.
Cela se réjouit d'un sujet sans rapport avec la question initiale. Il me semble que si j'ai un flux d'entrée, tel qu'un fichier plat ou des informations provenant d'Internet, je pourrais écrire toutes ces données sur une table, puis effectuer une seule mise à jour à l'aide de cette table. Mais je suppose que cela serait que cela serait plus lent, comme s'il y en avait, disons 1000 enregistrements, je devrais faire 1000 inserts, puis 1 grande mise à jour, plutôt que 1000 mises à jour. Je soupçonnerais que 1000 inserts prendraient plus de 1000 mises à jour. Dépend probablement beaucoup sur les détails du schéma et du fonctionnement du moteur.
Dans SQL Server, vous pouvez insérer en vrac à une table de mise en scène et effectuer une insertion à base de jeu ou vous pouvez utiliser une table Varaiiotable Ina Proc pour tirer toutes les données ou vous pouvez utiliser SSIS. Tous ceux-ci seraient probablement plus rapides pour tout grand nombre d'enregistrements que de boucler. Bien sûr, 1000 enregistrements est minuscule, mais vous devriez utiliser des méthodes définies de toute façon parce que 1000 insérons d'enregistrement ont maintenant tendance à constituer un million d'inserts d'enregistrement en six mois. Et vous devez cesser de penser à boucler comme un choix viable.
En supposant que la capacité de retourner la persistance de toute la persistance n'est pas nécessaire (auquel cas il n'y a qu'une seule réponse; s'engager à l'extérieur), commettre à l'intérieur de la boucle maintient le journal de transaction plus petit, mais nécessite plus de ruptures à la DB. L'engagement en dehors de la boucle est l'exact opposé. Ce qui est plus rapide dépend du nombre d'opérations moyen et de la quantité de données à commérer globalement. Pour une routine qui persiste environ 10-20 enregistrements, engagez-vous en dehors de la boucle. Pour les enregistrements de 1M-2M, je vous engagerais dans des lots. P>
En termes de performance, il est généralement préférable de faire une grande validation à la fin (laisser le trafic de réseau, normalement moins de travail pour la DB). P>
Ceci dépend bien sûr de nombreux facteurs, tels que l'indexation sur la table, la quantité de données, etc. P>
Que devrait conduire votre décision est l'importance chaque mise à jour em> est - devrait-elle être une transaction en soi? Une mise à jour de nombreux articles a-t-elle un sens? Que se passe-t-il si la boucle échoue à mi-chemin? P>
Répondre à ces questions vous donnera la bonne façon de le faire dans votre demande de ce processus - vous pouvez arriver à différentes manières de gérer la validation en fonction du contexte de l'application. P>