Bonjour,
Je travaille depuis plusieurs jours sur un script très gourmand en temps et en mémoire.
Ce script parse des flux xml et enregistre le flux dans une base de données mysql ou bien met la base de données à jour.
pour les petits flux ça marche pas mal quelques soit la procédure.
J'ai par contre des flux contenant 70 000 et 140 000 articles et c'est la que ça se complique.
Par exemple le fichier xml contenant 70 000 articles fait 65MB et l'exécution du script actuel qui met à jour la base de données met 2h47mn a en voir le bout en local avec wamp. pour le deuxième je n'ai pas encore essayé.
Mais ça marche, ce qui est déjà pas mal, il n'y a plus qu'a améliorer tous cela.
Je voulais donc avoir votre opinion sur les différentes étapes de mon script.
1er Solution:
- Je vais chercher la référence unique de tous les articles qui existe déjà dans la BDD pour ce flux et je les mets dans un tableau $articles_existant.
- Je crée deux tableau vide $nouveau_art et $modif_art.
- je parse le flux avec sax donc en évènementielle qui fonctionne très bien même avec les gros fichiers.
- Dans mon parseur de flux, a chaque nouvel article je fais un foreach sur $articles_existant afin de voir si cet article est déja présent dans la base.
- Si l'article est déja présent dans la base, je le met dans $modif_art et s'il n'est pas présent dans $nouveau_art.
- Une fois tous le flux parser, j'ajoute tous les articles de $nouveau_art dans la base et je modifie tous les articles de $modif_art.
- Fin du script.
Probléme
- pour les gros flux j'ai le message d'erreur comme quoi la mémoire est insuffisante, je ne sais plus le terme exact, j'ai pourtant 128M de mémoire dispo. Mais comme le flux fait déja 65MB + le tableau des articles existants + quelques fioritures dont je n'ai pas parlé ci-dessus. ca plante.
2éme Solution:
- Je vais chercher la référence unique de tous les articles qui existe déjà dans la BDD pour ce flux et je les mets dans un tableau $articles_existant.
- Je crée deux tableau vide $nouveau_art et $modif_art.
- je parse le flux avec sax donc en évènementielle qui fonctionne très bien même avec les gros fichiers.
- Dans mon parseur de flux, a chaque nouvel article je fais un foreach sur $articles_existant afin de voir si cet article est déja présent dans la base.
- Si l'article est déja présent dans la base, je le met dans $modif_art et s'il n'est pas présent dans $nouveau_art.
- Dans mon parseur, je compte le nombre d'articles parser.($nb)
- Tous les 5000 articles parser, j'ajoute tous les articles de $nouveau_art dans la base et je modifie tous les articles de $modif_art.
- Je vide mes 2 tableaux $nouveau_art et $modif_art pour libérer de la mémoire et je continu par paquet de 5000.
- Fin du script.
Probléme
- Ca plante, et je ne sais pas pourquoi. une fois il me fait 1 seule boucle (5000 articles), une fois 3 (15 000) ou autre et pas forcément des boucles complète !!! j'ai l'impression que le temps d'enregistrer les données dans la BDD, il perd le flux!!! Bizarre
3éme Solution:
- Je crée une table par exemple:table2 ou je vais enregistrer le flux et faire ma mise à jour dans un deuxième temps.
- Je parse tous le flux et je l'enregistre dans table2.
- je fais une requête avec jointure pour ressortir les articles qui existe dans table2 et pas dans table. ce qui me donne les nouveaux articles.
- Je vais chercher tous les nouveaux articles de table2 et je les ajoutes dans table.
- Je supprime les nouveaux articles de table2.
- Je vais chercher tous ce qui reste dans table2 et je modifie les articles dans table.
- Fin du script.
Probléme
- Ca marche en 2h47mn pour le flux de 65MB
Qu'en pensez vous ?
Auriez-vous un raisonnement différents ?
Un retour d'expérience peut-être.
Merci d'avance.
Partager