Gros fichier XML (500mo) => BDD : Quelle technique ?

WRInaute discret
Bonjour,

Je souhaite parser un gros fichier XML de 500mo et stocker les données dans une base mysql.
Je veux récupèrer seulement le contenu de certaines balises du fichier XML.
Je veux le parser rapidement car je souhaite mettre à jour toutes les 24h.

J'aurais 2 questions :

Selon vous quelle est la méthode la plus efficace ? simplexml convient ? SAX ? ...

Je dispose d'une dédibox, je sais que ce sont pas les meilleurs serveurs mais j'ai pas un gros budget. Est ce que ca suffit pour réaliser ceci ?

Merci de votre aide.
 
WRInaute discret
Je sais pas du tout si cela peut etre parser rapidement sur une dédibox mais le mieux c'est que tu essayes.

Après si c'est vraiment trop long tu peux, peut etre, enlever les balises inutile de ton xml avant traitement (un coup de grep -v )
Bon j'ai aucune idée des performances en faite, je dis surement des conneries ! Faut tester quoi :lol:
 
WRInaute impliqué
Salut,
J'ai été confronté à la même problèmatique pour mon www, et la réponse et oui c'est possible. En utilisant XMLReader de php5 tu liras sans problème tes 500mo, tu arriveras à faire les insert dans MySQL aussi.
Maintenant pour la mise à jour quotidienne, il est plus rapide de mettre à jour que d'effacer et de recommencer. Il est aussi plus rapide de ne pas faire l'update si l'on sait pertinement que le produit n'a pas bouger. Cela peut se détecter avec un crc32. Il faut aussi être en mesure de supprimer les produits qui ne sont plus dans le flux et aussi ajouter ceux qui n'existait pas.
Alors une dedibox fera très bien l'affaire, seulement si ton serveur a du traffic il faut s'avoir qu'il va en prendre un coup pendant quelques dizaines minutes chaque jour au moment de la mise à jour et que du coup ton site va ramer.
Après c'est flux de 500Mo c'est tentant pour mettre du contenu sur son site (les descriptions, le nom de produits :wink: ) mais pour google ce n'est pas du contenu original autant dire que le réf n'est pas acquis
 
WRInaute discret
julienr a dit:
Maintenant pour la mise à jour quotidienne, il est plus rapide de mettre à jour que d'effacer et de recommencer. Il est aussi plus rapide de ne pas faire l'update si l'on sait pertinement que le produit n'a pas bouger. Cela peut se détecter avec un crc32. Il faut aussi être en mesure de supprimer les produits qui ne sont plus dans le flux et aussi ajouter ceux qui n'existait pas.

Quand tu dis que tout recommencer prends plus de temps, celà prends beaucoup plus de temps ou juste un petit peu ?

Sinon je n'ai pas compris comment le crc32 peut nous permettre de voir si le produit a changé ou non.
Je vois pas le rapport, si tu pouvais m'expliquer.

Merci :)
 
WRInaute impliqué
clairement effacer tout pour réinserrer tout alors qu'au final y a moins de 10% qui a changé ca vaut pas le coup, c'est de l'ordre d'un rapport de 1 à 5 :-(

alors l'algo que j' utilise est le suivant (c'est pas forcément le meilleure) :

1- je parcours la table des produits et je stocke dans un tableau l'id_produit (l'auto incrément), la ref_produit (du catalogue), le crc32 (des data)

2- je parcours ensuite séquentiellement le flux xml avec le xmlReader

3- pour chaque produit je regarde si j'ai déjà cette réf dans le tableau, si oui je calcule le crc32 des champs et je le compare à celui que j'ai dans le tableau, si c'est le meme crc32 pas besoin d'update je continue, sinon update du produit. Je marque aussi dans le tableau que la ref existe toujours. Si la ref n'existe pas encore insert

4- je parcours le tableau et je repère les produits qui ne sont pas marqué et donc qui doivent être supprimé, delete dans la base

un ordre d'idée : pour un flux de 10000 produits si aucune modif pas d'écriture base, le script mets pas plus de 3s
 
WRInaute occasionnel
un preg match all sur 500 mo de csv ?

drapal sur la discussion, j'ai croisé tes questions sur le chat, masterlud, et je suis sur les memes problematiques, toujours à la recherche d'une solution miracle (pour parser des fichiers de 2-300 mo, identifier des ngrammes, etc)
 
WRInaute occasionnel
De la responsabilité pénale du Président de la République

Avril 2007 : Nicolas Sarkozy aurait négocié le soutien de Jacques Chirac contre ...
Janvier 2007 : Roger-Gérard Schwartzenberg (député radical de gauche) : contre le nouveau statut pénal du chef de l'Etat ; Robert Badinter (sénateur socialiste) :"La révision est dangereuse" (pour la gauche) ; premier vote à l'Assemblée nationale ; adoption par le Congrès le 19 février 2007
Décembre 2006 : On avance ... ; vers une mise en cause ?
Octobre 2002 : Statut pénal : les "sages" au travail ......

Sous la présidence de M. Valéry Giscard d'Estaing

Le 3 décembre 1974 M. Valéry Giscard d'Estaing, élu président de la République le 19 avril 1974, est relaxé par la 17ème chambre du Tribunal correctionnel de Paris devant lequel il était actionné pour complicité d'infractions à la législation sur l'affichage électoral pendant la campagne présidentielle.
Le tribunal s'est déclaré compétent, cette compétence n'ayant "jamais été contestée par Valéry Giscard d'Estaing, malgré son accession à la présidence de la République".

Sous la présidence de M. Jacques Chirac

extraction de ngrammes =

"jacques chirac"
"président de la république"
"valery giscard d'estaing"
"sous la présidence de "
"statut pénal"
etc..

les ngrammes sont des groupes de mots fréquemment rencontrés dans un corpus textuel
 
WRInaute impliqué
Malaiac a dit:
dans un corpus textuel
:D

Malaiac a dit:
"jacques chirac"
"président de la république"
"valery giscard d'estaing"
"sous la présidence de "
"statut pénal"
etc..
bah çà c'est une problématique de calcul de densité, c normalement pas un algorithme couteux...
 
WRInaute occasionnel
un peu couteux quand meme :D

si tu pars sur 200 mo de texte, meme en limitant la recherche à pondérer les ngrammes déja connus (quelques milliers on va dire), y a de quoi mettre à plat un serveur si tu l'attaques en direct, et une question de scalabilité si tu veux assurer la répétition du process (aujourd'hui, ce probleme la, je l'ai sur un corpus textuel de ~ 25 gig de pur texte)

A moins que tu aies des solutions simples et efficaces, et dans ce cas je suis preneur (contre $$ si c'est robuste et opérationnel)

tu as mon mail :)
 
WRInaute impliqué
intéressant :) mais pas pour des $$ j'aurais pas cette prétention !
Malaiac a dit:
aujourd'hui, ce probleme la, je l'ai sur un corpus textuel de ~ 25 gig de pur texte
et tu as quelque chose qui tourne là actuellement ? Quelles sont les limites que tu rencontres, problème de mémoires, de cpu, de temps de traitement ? A partir de combien de Mo de donnée traitée ca bloque ?

Sinon quand je dis pas trop couteux, c'est que pour moi au niveau de compléxité c'est du O(1) tu lis qu'une fois les données...
 
WRInaute discret
julienr a dit:
oui enfin pour être plus précis je lis chaque ligne du csv que je passe dans un preg_match_all

Sur le tchat, on m'a parlé de fgetcsv(), pourquoi tu ne l'utilises pas ?

Sinon ce n'est pas trop long de faire ligne par ligne ?
Sur le forum, on m'avait conseillé de faire une boucle qui traite 100 lignes par 100 lignes.

Malaiac >> Tu veux parser du CSV ou du XML ?
 
WRInaute impliqué
ouai bah je sais pas si c'était un bon conseil...

par acquis de conscience je viens de faire un petit bench entre les deux solutions sur mon plus gros csv qui fait exactement 14585870 octets

alors avec ma méthode actuelle : while fgets preg_match_all
je traite le fichier en moyenne 0.887844085693

avec la méthode while fgetscsv
le traitement dure en moyenne 5.60947990417 !!!!
j'ai essayé de faire varier le paramètres à 100 ou 1 ou 1000 même résulat
 
WRInaute discret
D'après lui, ca vient surement de l'évolution depuis php4.
Finalement je vais plutôt utiliser fgets preg_match_all alors (de toutes façons, les 2 se rapprochent)
 
WRInaute discret
Oui, c'est possible que ça ait évolué depuis php4 :)
A l'époque où j'avais testé, fgetcsv() était très utile et plutôt rapide, mais il est possible que, du fait de son utilisation limitée, elle n'ait pas été améliorée depuis, contrairement au couple fgets() et preg_match_all().
 
WRInaute discret
Pas mal, mais pour ton fichier de 500Mo, il va créer un grooooooos tableau de données, et ça tiendra jamais le coup :)
 
WRInaute occasionnel
sans vouloir paraitre vieux jeu avec un langage d'un autre temps, si tu tournes sur une dedibox, un ptit programme C++ ( en utilisant la librairie mysql++ ) permettrait beaucoup plus de flexibilité au niveau du controle du temps processeur, etc... et si t'as vraiment besoin de regex, y'a une librairie ( boost ) qui fournit une implémentation.

Si tu codes couramment en php, tu n'auras pas (trop) de mal à écrire une moulinette en c++, avec un peu de lecture et un poil de courage.

amha le jeu en vaut la chandelle
 
WRInaute discret
Oui clairement, je dirai même plutôt C (car au moins, on est sûr que le compilateur C est compris sur une dedibox). J'avais proposé cette solution sur le chat :)
Et si t'es chaud bouillant, tu nous le fais en bash :D
 
WRInaute occasionnel
je reprends le fil :
- pour l'instant est dans plusieurs tgz, contenant des palanquées de fichiers .csv (50-60 000 fichiers par archive de 250 mo)
- limites : j'avais fait quelques tests en php. autour de 40 50 mo de texte, ca commencait à peter. un des principaux soucis est de charger les 3-4000 ngrammes deja connus en mémoire, et de faire tourner les fonctions nécessaires à les protéger de l'explode.
 
WRInaute occasionnel
Bh@Mp0 a dit:
Oui clairement, je dirai même plutôt C (car au moins, on est sûr que le compilateur C est compris sur une dedibox). J'avais proposé cette solution sur le chat :)
Et si t'es chaud bouillant, tu nous le fais en bash :D

Si la dédibox tourne sous debian, y'a fatalement gcc.
 
WRInaute discret
NextGeneration a dit:
Bh@Mp0 a dit:
Oui clairement, je dirai même plutôt C (car au moins, on est sûr que le compilateur C est compris sur une dedibox). J'avais proposé cette solution sur le chat :)
Et si t'es chaud bouillant, tu nous le fais en bash :D

Si la dédibox tourne sous debian, y'a fatalement gcc.

Sur n'importe quel distro linux en fait, y'a fatalement gcc. Bon après, avoir un dédié sous windows, faut déjà le faire ...
 
WRInaute impliqué
Malaiac a dit:
50-60 000 fichiers par archive de 250 mo
tu voulais dire 250ko, sans doute ?

Je serais interessé à titre privé de conaitre le site, le domaine d'activité qui demande une telle information : connaitre les 1000 premiers ngrammes de 12 Go de text brut ? C'est de l'ordre de la statistique ou cela à une utilitée pour l'internaute : faire une recherche full text sur un ngramme dans les 12Go
(et dans ce cas ce n'est que le début de la fin...) ou autre ?

Sinon depuis longtemps je cherchais un interet à utiliser une base SqlLite à cause des problème de concurence qu'il peut y avoir sur le web. Mais là dans ce cas est-ce que ca permetterais pas de stocker le ngrammes ?
 
WRInaute discret
julienr a dit:
ouai bah je sais pas si c'était un bon conseil...

par acquis de conscience je viens de faire un petit bench entre les deux solutions sur mon plus gros csv qui fait exactement 14585870 octets

alors avec ma méthode actuelle : while fgets preg_match_all
je traite le fichier en moyenne 0.887844085693

avec la méthode while fgetscsv
le traitement dure en moyenne 5.60947990417 !!!!
j'ai essayé de faire varier le paramètres à 100 ou 1 ou 1000 même résulat

Quand tu dis "traiter", c'est juste le parsage ?
Ou tu utilise l'algo que tu m'as montré avant aussi dans ton traitement ?
 
Discussions similaires
Haut