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

ORM PHP Discussion :

[Doctrine] Récupérer une "grosse" quantité de données via doctrine pour un export


Sujet :

ORM PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2008
    Messages : 46
    Par défaut [Doctrine] Récupérer une "grosse" quantité de données via doctrine pour un export
    Salut,

    Je rencontre un problème avec symfony et plus particulièrement Doctrine. En fait, je voudrais récupérer une "grosse" quantité (elle me semble pas si énorme que cela à mes yeux ...) de données afin de les exporter dans un fichier CSV.

    J'ai 4 table liées entres-elles à récupérer : une Participation "has many" Newsletters, Fields et Questions.

    Voilà le schéma correspondant aux 4 tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    QuizgenParticipation:
      actAs: { Timestampable: ~ }
      columns:
        quiz_id:      { type: integer, notnull: true }
        civility:     { type: string(255), notnull: true }
        birthdate:    { type: timestamp, notnull: true }
        firstname:    { type: string(255), notnull: true }
        lastname:     { type: string(255), notnull: true }
        city:         { type: string(255), notnull: true }
        zip_code:     { type: string(255), notnull: true }
        email:        { type: string(255), notnull: true }
        accept_rules: { type: boolean, notnull: true, default: NULL }
        shares:       { type: integer, notnull: true, default: 0 }
      relations:
        QuizgenQuiz: { onDelete: CASCADE, local: quiz_id, foreign: id, foreignAlias: QuizgenParticipations } 
        QuizgenNewsletters:
          class: QuizgenNewsletter
          refClass: QuizgenParticipationNewsletter
          local: participation_id
          foreign: newsletter_id
          foreignAlias: QuizgenParticipations
        QuizgenFields:
          class: QuizgenField
          refClass: QuizgenParticipationField
          local: participation_id
          foreign: field_id
          foreignAlias: QuizgenParticipations      
        QuizgenQuestions:
          class: QuizgenQuestion
          refClass: QuizgenParticipationQuestion
          local: participation_id
          foreign: question_id
          foreignAlias: QuizgenParticipations 
     
    QuizgenParticipationQuestion:
      columns:    
        participation_id:  { type: integer, notnull: true }
        question_id:       { type: integer, notnull: true }
        answer:            { type: string(255), notnull: true }
      relations:
        QuizgenParticipation: { onDelete: CASCADE, local: participation_id, foreign: id }     
        QuizgenQuestion:      { onDelete: CASCADE, local: question_id, foreign: id }   
     
    QuizgenParticipationNewsletter:
      columns:    
        participation_id:  { type: integer, notnull: true }
        newsletter_id:     { type: integer, notnull: true }
      relations:
        QuizgenParticipation: { onDelete: CASCADE, local: participation_id, foreign: id }     
        QuizgenNewsletter:    { onDelete: CASCADE, local: newsletter_id, foreign: id }
     
    QuizgenParticipationField:
      columns:    
        participation_id:  { type: integer, notnull: true }
        field_id:          { type: integer, notnull: true }
        value:             { type: string(255) }
      relations:
        QuizgenParticipation: { onDelete: CASCADE, local: participation_id, foreign: id }     
        QuizgenField: { onDelete: CASCADE, local: field_id, foreign: id }
    Comme vous vous en doutez, QuizgenParticipationField, QuizgenParticipationNewsletter et QuizgenParticipationQuestion sont liés à d'autres infos, mais je n'en ai pas besoin ici.

    Il y aura entre 1000 et 5000 participations à exporter. Chaque participation est suceptible de posséder environ une 10aine de questions, 3 champs et 3 newsletters.

    J'ai donc optimisé ma requete DQL en faisant des leftJoin pour n'avoir qu'une seule requête de générée. J'ai également hydraté cela en tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     public function getParticipationsForQuiz($quizId)
      {
        $q = $this->createQuery('p INDEXBY p.id')
          ->where('p.quiz_id = ?', $quizId)
          ->leftJoin('p.QuizgenParticipationField pf INDEXBY pf.field_id')
          ->leftJoin('p.QuizgenParticipationNewsletter pn INDEXBY pn.newsletter_id')
          ->leftJoin('p.QuizgenParticipationQuestion pq')
          ->orderBy('p.id');
     
          return  $q->execute(array(),Doctrine::HYDRATE_ARRAY);
      }
    Le problème,c 'est que malgré ça, pour seulement 800 participations (10 questions pour chaque participation), ça me prend 23 secondes d'execution et 37Mo en mémoire ! Mais il ne m'est pas possible de dépasser 16Mo de mémoire.

    Qu'est ce qui n'est pas correct dans ce que j'ai fait ? Comme se fait-il que ma requête nécessite autant de mémoire ?

    Merci d'avance pour votre aide !

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Hello, t'as les droit sur FILE dans ta base (si t'es en mysql) ?

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2008
    Messages : 46
    Par défaut
    Hmm, bonne question.

    Selon toi, je ne peux pas m'en sortir avec Doctrine ?

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    il faudrait déjà retourner le statement plutôt que l'array complet la tu prends de la mémoire pour rien

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2008
    Messages : 46
    Par défaut
    J'ai pensé à cela mais en passant par PDO directement. Comment pourrais-je faire à partir de mon objet Doctrine_Query ?

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Citation Envoyé par Neveldo Voir le message
    J'ai pensé à cela mais en passant par PDO directement. Comment pourrais-je faire à partir de mon objet Doctrine_Query ?
    tu recuperes la requete via getSqlQuery, ensuite tu recuperes pdo via le Doctine_Connection::$dbh

Discussions similaires

  1. Réponses: 0
    Dernier message: 31/05/2011, 19h13
  2. Réponses: 3
    Dernier message: 10/11/2008, 11h58
  3. récupérer une image de la base de données
    Par ijklm dans le forum Struts 1
    Réponses: 6
    Dernier message: 24/05/2006, 09h59

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