Question

J'écris une application qui doit périodiquement (chaque semaine par exemple) parcourir plusieurs millions d'enregistrements dans une base de données et exécuter du code sur les résultats de chaque ligne.

Étant donné que la table est si grande, je soupçonne que lorsque j'appelle SomeObject.FindAll (), il lit toutes les 1,4 millions de lignes et tente de renvoyer toutes les lignes d'un objet SomeObject [].

Existe-t-il un moyen d'exécuter une expression SomeObject.FindAll () tout en chargeant les valeurs d'une manière plus conviviale pour les SGBD?

Était-ce utile?

La solution

Pas avec FindAll () - qui, comme vous l'avez supposé, essaiera de charger toutes les occurrences du type spécifié en même temps (et, en fonction de la manière dont vous avez défini NHibernate up peut émettre un nombre incroyable de requêtes SQL pour le faire).

Le chargement différé ne fonctionne que sur les propriétés des objets. Ainsi, par exemple, si le type persistant SomeObjectContainer avait pour propriété une liste de SomeObject mappé de telle manière qu'il corresponde à tous les SomeObject et qu'avec lazy = "true", utilisez un foreach sur cette propriété de liste, vous obtiendrez ce que vous voulez, en quelque sorte; Par défaut, NHibernate émettrait une requête pour chaque élément de la liste, en n'en chargeant qu'un seul à la fois. Bien sûr, le cache de lecture deviendrait gigantesque, vous auriez donc probablement besoin de vider beaucoup.

Ce que vous pouvez faire est d’émettre une requête HQL (ou même d’embedded SQL) pour récupérer tous les ID de tous les SomeObjects, puis de les parcourir un par un en récupérant l’objet correspondant avec FindByPrimaryKey. Encore une fois, ce n’est pas particulièrement élégant.

Pour être honnête, dans une situation comme celle-là, je transformerais probablement cela en travail de maintenance planifiée dans un processus stocké - à moins que vous ne deviez vraiment exécuter du code sur l'objet plutôt que de manipuler les données. en quelque sorte. Cela peut gêner les puristes d’objets, mais parfois une procédure stockée est la meilleure solution, en particulier dans ce type de scénario de traitement par lots.

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