IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Optimisation mémoire Datatable


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 13
    Par défaut Optimisation mémoire Datatable
    Bonjour,

    voici le contexte :
    Je récupère des données depuis une base de données Oracle grâce à un DataReader afin d'optimiser la gestion mémoire.
    De par les contraintes qui pèsent, je dois effectuer les opérations suivantes :
    à la table récupérée de la base Oracle, j'ajoute deux champs que je remplis par croisement (équivalent inner join) avec des tableaux.

    A terme, une fois la table finale constituée, je dois faire une exportation Excel.

    Problème :
    Tout simplement la volumétrie. L'action de parcourir le DataReader et d'ajouter chaque ligne à une table aboutit à une erreur OutOfMemoryException au bout de 3 millions de lignes. Sauf que je dois en traiter jusqu'à 20 millions.
    Et mes contraintes ne me permettent pas de filtrer directement sur la base pour concaténer tous les champs voulus au final.
    Je dois donc passer par cette étape intermédiaire.

    Ma question est la suivante :
    Existe-t-il un moyen d'utiliser les Datatable pour traiter une telle volumétrie ?
    Si non, est-ce même possible et par quel moyen ?
    J'avais pensé à une liste d'un type créé par mes soins, mais je préfère m'adresser à vous avant.

    Merci d'avance de votre aide.

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Par défaut
    J'en profite pour te rappeller qu'Excel gère environ 65'000 ligne en 2003, 1 million en 2007 et une centaine de million en 2010 a peu près (la limite est fixée par la ram de la machine, je suppose qu'il vaut mieux tourner sur du 64 bits aussi..). C'est juste histoire que tu ne pleure pas à la prochaine étape !

    Autrement pour résoudre ton problème, l'utilisation d'une liste de type pile (first-in, first-out) avec un thread qui remplit la liste depuis Oracle et un thread qui vide la liste en l'écrivant dans un fichier en parallèle est peut être une piste.

    Par contre il te faudra prendre un soin particulier à l'écriture de ton fichier afin que ce dernier ne soit pas chargé en mémoire sinon tu vas juste reporter ton problème de outofmemory plus loin.

    Faire une application x64 uniquement et sur une machine plus robuste en mémoire vive permet peut être aussi de résoudre le problème. A confirmer par un expert des limites de la gestion de la mémoire sur .Net

    Tu peux aussi mettre en place un système de pagination, qui te permet de ne pas traiter tous les résultats en une fois. (charge les x premiers résultats, tu copies dans un fichier Excel, tu vides la liste, tu charges les x résultats suivant, tu copies dans un fichier Excel, etc).

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 194
    Par défaut
    mettre x millions de lignes en ram dans .net pour les écrire après n'est pas toujours le mieux
    la méthode serait alors de lire un ligne, et de l'écrire dans la foulée, ou encore mieux comme le dit sinople de faire les 2 actions sur 2 threads (avec un queue et du thread safe ^^)

    par contre je pense comprendre dans ton message que tu aurais besoin de charger tout pour faire un "traitement" avant de savoir quoi sortir sur excel, auquel cas écrire au fur et à mesure n'est pas possible

    le datatable est un gouffre à mémoire et pas le mieux niveau performances, en plus c'est non managé il me semble
    une classe est donc le mieux, avec soit un list(of ), soit un dictionary(of ) si tu as besoin de retrouver rapidement un objet par sa clé


    après il faut voir aussi le nombre de lignes que tu veux sortir sur excel, et comment tu veux les sortir, si tu as besoin de réduire le temps d'écriture vers excel, tu peux utiliser oledb, mais ca ne permet pas de faire de mise en page comme par l'interop
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour Dullbrain

    msdn doc rubrique :
    Rubrique DataTable, classe
    Le nombre maximal de lignes pouvant être stockées dans un DataTable est de 16 777 216
    Maintenant concernant la datable ,le nombre de lignes ,meme s'il n'atteint pas la limite (16 millions) est "une virtualite" car la taille memoire requise par le dt est egale =longueur memoire d'un row x nbre de row.........sans compter comme l'as dit Pol63 :

    le datatable est un gouffre à mémoire et pas le mieux niveau performances, en plus c'est non managé il me semble
    une classe est donc le mieux, avec soit un list(of ), soit un dictionary(of ) si tu as besoin de retrouver rapidement un objet par sa clé
    De plus un objet a grande taille fixe pose des problemes ,car la memoire disponible est parfois "fragmentee" (elle est allouee sur le heap par le clr)......................

    bon code.....................

  5. #5
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Bonjour,

    Citation Envoyé par Dullbrain Voir le message
    voici le contexte :
    Je récupère des données depuis une base de données Oracle grâce à un DataReader afin d'optimiser la gestion mémoire.
    De par les contraintes qui pèsent, je dois effectuer les opérations suivantes :
    à la table récupérée de la base Oracle, j'ajoute deux champs que je remplis par croisement (équivalent inner join) avec des tableaux.
    A terme, une fois la table finale constituée, je dois faire une exportation Excel.
    A première vue, ton choix architectural pour ton appli me parait complétement farfelu.

    Quelle est l'utilité de passer par une DataTable ? en quoi bouffer le maximum de mémoire optimise-t-il quoi que ce soit ?

    Qu'est ce qui t'empêche d'écrire tes données en rajoutant tes champs dans une table temporaire locale (par exemple, tu as les Global|Local Temporary Table sur ORACLE), puis lire cette table et écrire dans Excel directement ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 13
    Par défaut
    Merci à tous pour vos réponses.

    @Sinople : merci, j'ai bien pris en compte la limitation au niveau du nombre de lignes d'Excel, c'est pou cela qu'une condition me permet de scinder l'exportation d'un panel en plusieurs classeurs. De ce fait, la consommation mémoire ne devrait pas être excessive étant donné qu'en moyenne 600,000 lignes seront écrites à chaque fois grâce à des variables libérées à chaque itération. J'espère avoir tout pris en considération.

    @Pol63 : Merci pour ce renseignement sur le caractère gourmand des datatable. Et en effet, je dois ensuite effectuer des filtres et traitements qui selon moi nécessitent d'abord de disposer de la totalité des données mises en forme.

    @Bluedeep : le contexte entreprise dans lequel je travaille ne me laisse comme unique latitude le rapatriement des données par requête. Après, je pratique le VB sans formation aucune donc il est tout à fait possible que ma méthode soit farfelue, aberrante, stupide.... (qualificatif à ta discrétion).
    Le problème est que les champs que je dois ajouter viennent d'une autre base de données, c'est pourquoi j'opère la concaténation a posteriori. Par la suite, je dois encore réaliser un export par type de panel (un des champs de ma table mise en forme), donc j'ai besoin de filtrer avant d'exporter.

  7. #7
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par Dullbrain Voir le message
    Le problème est que les champs que je dois ajouter viennent d'une autre base de données, c'est pourquoi j'opère la concaténation a posteriori.
    Je travaille plutôt avec sql server qu'oracle mais ça m'étonnerait que vous ne puissiez faire de requêtes multi-bases sur oracle.

    A votre place, je chercherais plutôt à optimiser la requête pour n'obtenir que les résultats dont vous avez besoin.

    Parce qu'exporter 3 millions de ligne pour au final ne peut-être en traiter qu'une poignée, je ne pense pas que cela soit une bonne solution.

Discussions similaires

  1. Configuration/Optimisation Mémoire Oracle 10g
    Par jfmerveille dans le forum Oracle
    Réponses: 1
    Dernier message: 13/02/2012, 12h35
  2. Optimisation mémoire - Garbage collector
    Par MisterMok dans le forum Framework .NET
    Réponses: 1
    Dernier message: 07/11/2011, 14h31
  3. [Optimisation] Mémoire occupée par des images
    Par Crowell dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 23/05/2007, 16h34
  4. Optimisation mémoire sur des String
    Par CyberChouan dans le forum Langage
    Réponses: 6
    Dernier message: 25/02/2007, 20h25
  5. optimisation mémoire
    Par cgu dans le forum Général Java
    Réponses: 11
    Dernier message: 04/04/2006, 22h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo