parser très gros fichier texte

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

04 juil. 2006, 23:57

Attention, l'option REPLACE pourrait être incompatible avec la désactivation des indexes.

Essaie de comparer LOAD DATA ... REPLACE et un TRUNCATE suivi de LOAD DATA (avec indexes désactivés) il est souvent plus rentable de faire de nombreux INSERT dans une table vide que des REPLACE sur une table pleine.

Mammouth du PHP | 19672 Messages

05 juil. 2006, 07:28

Merci pour l'info, je vais tester ça dans la matinée et je ferai des bench pour vérifier :)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 254 Messages

05 juil. 2006, 11:09

......., mais je cherche une manière d'accélérer un brin le processus : est-ce que l'un d'entre vous aurait une idée à me suggérer.
cache d'opcode pour TOUS les traitements un peu trop lourd pour la memoire ou le processeur :!:
mise en cache du code, tu diviseras au minimum par 2 le temps mais il restera le probleme du temps total de traitement car pour traiter des fichiers CSV de 100Mo je mets dans les 8mn :?

-zend cache (payant !)
-APC (gratuit) http://pecl.php.net/package/APC
-.... il y en a beaucoup d'autres ...

pour PHP, tu peux aussi te creer tes propres fonctions dans des DLL que tu charges par dl() mais mon niveau n'est pas assez bon en C ou delphi pour te donner + d'infos ...

il existe la meme soluce pour MySQL

Mammouth du PHP | 1311 Messages

05 juil. 2006, 11:28

au passage
etant que cyrano pense utilisé MySQL 5, aurait-il interet a utilisé une procedure stockée???

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 juil. 2006, 13:43

cache d'opcode pour TOUS les traitements un peu trop lourd pour la memoire ou le processeur :!:
Attention à ne pas confondre, les caches d'opcode n'accélèrent que le démarrage du programme mais une fois le fichier chargé en mémoire ils ne servent plus à rien. Ils ne modifient pas son utilisation de la mémoire ou du processeur. Pour être complet, on pourrait dire que la plupart des caches d'opcodes possèdent également un optimiseur, mais leur action est généralement extrêmement limitée (moins de 1% d'amélioration).
mise en cache du code, tu diviseras au minimum par 2 le temps [...]
Ça je n'ai pas compris, de quel cache parles-tu ?

Mammouth du PHP | 19672 Messages

05 juil. 2006, 15:38

Le problème est résolu et la vitesse m'a carrément scotché, voyez plutôt :

Code : Tout sélectionner

mysql> LOAD DATA LOCAL INFILE 'G:/www/tmp/******/***********/addition.txt' -> IGNORE -> INTO TABLE `Addition` -> FIELDS TERMINATED BY '\t' -> LINES TERMINATED BY '\n' -> (`ADDMarket`, `ADDVehType`, `ADDID`, `ADDNatCode`, `ADDEQCode`, -> `ADDVal`, `ADDValUntil`, `ADDCurrency`, `ADDPrice1`, `ADDPrice2`, -> `ADDTaxRt`, `ADDTax1`, `ADDTax2`, `ADDNet`, `ADDFlag`, -> `ADDFlagPack`, `ADDStatus`, `ADDRecStatus`, `ADDRecDate`, `ADDTargetGrp`, -> `ADDAssemble`, `ADDMerchantCode`, `ADDValNewPr`); Query OK, 7583821 rows affected, 65535 warnings (1 min 16.53 sec) Records: 7583821 Deleted: 0 Skipped: 0 Warnings: 7583821
7,5 millions de lignes en moins de deux minutes, je crois que la question est quasiment réglée.

Il me reste toutefois un problème avec certains fichiers dont certains champs n'ont pas de donnée du tout, ce qui fait que j'ai deux tabulations cosécutives : le retour est une erreur comme ceci:

Code : Tout sélectionner

ERROR 1265 (01000): Data truncated for column 'EXCTax1' at row 1
Je résouds le problème en ne mettant pas le champ concerné dans la liste parce que toute le colonne est pareille, mais existe-t-il une solution au cas où j'aurais la donnée sur certaines lignes seulement ? Attention, je n'ai absolument aucun contrôle possible sur l'export du fichier utilisé. En clair, comment indiquer qu'il faut insérer "NULL" dans la colonne s'il n'y a rien entre les deux tabulations ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 505 Messages

05 juil. 2006, 17:35

Lors de la création de table, pour chaque colonne, essai de mettre une valeur par default à NULL

Mammouth du PHP | 19672 Messages

05 juil. 2006, 17:39

Merci pour cette réponse titerm, mais ça fait bien longtemps que c'est fait d'une part, et d'autre part, le problème se pose au moment de récupérer la donnée (absente) dans le fichier pour l'envoyer vers la table, et non au moment de l'insertion.

Comme j'envoie vers une base de transit, je me suis pas embarrassé de détails pour les types de champs et les valeurs par défaut (pratiquement tout à NULL). Après il sera toujours temps de fignoler pour envoyer vers la vraie base définitive avec tous les détails voulus, mais avec entre autres un fichier de + de 670Mo, je peux pas finasser.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 19672 Messages

06 juil. 2006, 09:31

Bon, ben j'ai résolu : le type de champ bloquant est théoriquement un FLOAT, mais l'importation de la donnée absente posait problème malgré une valeur par défaut à NULL. comme c'est une base de transit, j'ai modifié le type de champ par un VARCHAR... et là tout est rentré dans l'ordre.

Sujet donc résolu, merci à chacun.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe: