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

Langage PHP Discussion :

Corriger proprement ? "Fatal Error Allowed Memory Size Exhausted"


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Points : 29
    Points
    29
    Par défaut Corriger proprement ? "Fatal Error Allowed Memory Size Exhausted"
    Salut à tous,

    Je cherche un moyen pratique et surtout propre pour éviter une erreur de mémoire dépassée sous PHP.

    Sur ma page, un tableau est généré à partir d'informations dans des bases de données, puis ce tableau est retranscrit en HTML (tr, td).

    Etant donné que le tableau généré à partir de la base compte 15 000 lignes et 15-20 colonnes, je pense que le soucis de mémoire saturée provient de là.

    J'ai lu par-ci par-la que le fait d'augmenter php.ini pour la valeur max de mémoire fonctionnait, mais je ne souhaite pas le faire : c'est pas très propre.

    Je cherche donc un moyen de réduire l'utilisation de la mémoire de PHP.

    A savoir :
    - les données du tableau sont récupérées dans 3 tables différentes
    - les données sont sous format texte.

    Merci d'avance

  2. #2
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Pourquoi ne serait-ce pas très propre d'augmenter la mémoire ? Cela peut être une solution tout à fait honnête, surtout si aucune autre optimisation n'est possible. Parfois, il faut juste se donner les moyens de sa politique.

    Peux-tu nous faire connaitre ton code pour que nous puissions en dire davantage ?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    Je ne peux malheureusement pas partager mon code.

    Je suis conscient de la solution php.ini, mais je préfère directement réduire l'utilisation mémoire car les données vont être de plus en plus importantes et prendre de plus en plus de mémoire (je prend le problème à la racine).

    Mon soucis est que les données se trouvent dans 3 tables avec des liens entre ces tables (une adresse e-mail). Pour chaque e-mail, on peut récupérer 1, 2 ou 3 informations.

    Dans la liste que je cherche à générer à la fin, il ne faut pas 3 fois l'e-mail avec une info, mais un e-mail avec 3 infos (récupérées dans 3 bases).

    C'est ce qui m'empêche de générer mon code HTML à la volée : les doublons entre les trois tables.

  4. #4
    Membre chevronné Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Points : 1 895
    Points
    1 895
    Par défaut
    est ce que ces informations ont besoin de se trouver sur la même page ?
    tu pourrais par exemple afficher 100 résultats par page

  5. #5
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Nous allons être obligés de taper au hasard...

    - Améliorer les perfs au niveau SQL : effectuer des jointures sur des informations indexées. En l'occurence, tes adresses mails. Sont-ce des clés primaires ?

    - Si j'ai bien compris, tu récupérais trois jeux de résultats, donc trois tableaux associatifs avec le mail comme clé. Effectivement, il serait souhaitable de trouver un algo pour n'avoir qu'une seul tableau, idéalement par une requête avec jointures.

  6. #6
    Nouveau membre du Club
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    En fait la pagination est déjà en place, mais derrière celle-ci on a toujours le tableau monstrueux qui bouffe la mémoire.

    Les adresses e-mail ne sont pas des clés primaires mais sont uniques dans chaque table.
    Mais il se peut qu'une adresse soit présente dans une table, mais pas dans une autre, ce qui me semble compliqué pour effectuer une jointure.

    En fait le seul résultat que je veux afficher c'est si oui ou non une adresse est présente dans une, deux ou trois tables.
    Donc actuellement un tableau est rempli, on passe en revue la première table, on enregistre les adresses e-mail dans le tableau et on note "présent dans la table 1", puis on parcours la deuxième table. On regarde si elle est déjà présente dans le tableau. Si oui on enregistre "présent dans la table 1 ET dans la table 2" sinon on ajoute l'adresse dans le tableau et on note "présent dans la table 2" (implicitement absent de la table 1).

  7. #7
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par Guillaume_Caldera Voir le message
    En fait la pagination est déjà en place, mais derrière celle-ci on a toujours le tableau monstrueux qui bouffe la mémoire.

    Les adresses e-mail ne sont pas des clés primaires mais sont uniques dans chaque table.
    Mais il se peut qu'une adresse soit présente dans une table, mais pas dans une autre, ce qui me semble compliqué pour effectuer une jointure.

    En fait le seul résultat que je veux afficher c'est si oui ou non une adresse est présente dans une, deux ou trois tables.
    Donc actuellement un tableau est rempli, on passe en revue la première table, on enregistre les adresses e-mail dans le tableau et on note "présent dans la table 1", puis on parcours la deuxième table. On regarde si elle est déjà présente dans le tableau. Si oui on enregistre "présent dans la table 1 ET dans la table 2" sinon on ajoute l'adresse dans le tableau et on note "présent dans la table 2" (implicitement absent de la table 1).
    Ouah, c'est clair que ça peut être optimisé.

    =>Indexer les adresses mails, avec null autorisé.

    => Les jointures peuvent vraiment aider :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    select tb1.mail, tb2.mail, tb3.mail FROM tb1 LEFT OUTER JOIN tb2 ON tb1.mail=tb2.mail LEFT JOIN tb3 ON tb1.mail=tb3.mail
    Ce style de requête te donne un jeu de résultats directement exploitable.

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Juin 2004
    Messages
    772
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2004
    Messages : 772
    Points : 872
    Points
    872
    Par défaut
    Citation Envoyé par Guillaume_Caldera Voir le message
    En fait la pagination est déjà en place, mais derrière celle-ci on a toujours le tableau monstrueux qui bouffe la mémoire.
    Si tu rajoutes une clause LIMIT nb_elem à ta requête avec un OFFSET start_from qui se décale de page en page tu ne remplis ton tableau que de nb_elem elements à chaque fois... Fini le monstre non ?

  9. #9
    Nouveau membre du Club
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Points : 29
    Points
    29
    Par défaut
    pc.bertineau, ta solution me semble bonne, cependant, je dois avouer que la solution SQL de Snafu est fonctionnelle avec mes données et me parait plus simple à adapter dans mon fichier.

    Je ne connaissais pas cette syntaxe et je dois avouer qu'elle est parfaitement adaptée.

    Merci beaucoup, je passe demain à l'adaptation de cette requête sur mon fichier.
    En attendant, je vais déclarer mon problème comme résolu (l'adaptation ne me semble pas être un problème).

  10. #10
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Citation Envoyé par Guillaume_Caldera par message privé
    Hello !

    Je voulais te remercier pour ton coup de main pour la requête SQL.

    Cependant, je voulais savoir si tu pouvais m'aider à finaliser cette requête.

    SELECT tb1.mail, tb2.mail, tb3.mail FROM tb1 LEFT OUTER JOIN tb2 ON tb1.mail=tb2.mail LEFT JOIN tb3 ON tb1.mail=tb3.mail

    La requête renvoie les entrées de tb1.mail et si il y'a une même entrée de mail sur la tb2 et la tb3.

    Cependant, la requête ne tient pas compte de la possibilité qu'une personne soit inscrite à la tb2 mais ne le soit pas dans la tb1, même chose pour la tb3.

    (La requête renvoie les entrées de la tb1 qui ne sont pas dans tb2 et tb3. Par contre elle ne renvoit pas les entrées de tb2 qui ne sont pas dans tb1 et tb3.)

    Je suis à la recherche de la solution. Cependant si tu as une idée pour me débloquer, je t'en serai reconnaissant. Merci d'avance.
    Merci pour le MP, mais je préfère répondre en public pour avoir des relecteurs et des correcteurs ou cas où je me plante.

    Les perfs vont reflétées le fait qu'il n'y a aucune des tables qui soit une source complète pour les mails, mais c'est faisable :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    SELECT A.mail, tb1.mail, tb2.mail, tb3.mail 
    FROM 
    (
        SELECT mail FROM tb1
        UNION
        SELECT mail FROM tb2
        UNION
        SELECT mail FROM tb3
    ) AS A
    LEFT JOIN tb1 ON A.mail=tb1.mail
    LEFT JOIN tb2 ON A.mail=tb2.mail
    LEFT JOIN tb3 ON A.mail=tb3.mail
    ;

    Pour le coup, une indexation sur les mails devient cruciale.

    Et je vire le tag "résolu" en attendant que tu confirmes.

Discussions similaires

  1. [Images] Galerie photo (Fatal error: Allowed memory size)
    Par Dookie dans le forum Bibliothèques et frameworks
    Réponses: 15
    Dernier message: 25/05/2010, 12h13
  2. [PEAR][Mail] Fatal Error : Allowed memory size of 8388608 bytes exhausted
    Par bigben89 dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 20/10/2008, 18h01
  3. Réponses: 3
    Dernier message: 08/08/2007, 19h08
  4. [Librairies] zip.lib.php Fatal error: Allowed memory size of 8388608 bytes exhausted
    Par manaboko dans le forum Bibliothèques et frameworks
    Réponses: 9
    Dernier message: 22/05/2006, 10h42
  5. Fatal error: Allowed memory size of...
    Par Webfab dans le forum Langage
    Réponses: 3
    Dernier message: 17/09/2005, 10h11

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