Ah zut.Recif a dit:J'ai le process php5 qui est en haut du "top"...
$url = "http://www.siteweb.com/cron/products_fr.txt";
$file = fopen ("$url", "r");
while (!feof ($file)) {
$line = fgets ($file);
if (preg_match("@product_category@",$line)) { continue; }
$listl2 = explode(" ", $line);
$famille_id = "";
$marque_id = "";
$description = addslashes($listl2[4]);
$famarray = explode(">",$listl2[5]);
$nbre_sep = count($famarray);
$nbre_sep=$nbre_sep-1;
$famille = addslashes($famarray[$nbre_sep]);
$marque = addslashes($listl2[7]);
$modele = addslashes($listl2[1]);
$listl2[2] = trim(preg_replace("@\?utm_source=products\&utm_medium=merchant@i","",$listl2[2]));
$listl2[2] = $listl2[2]."/349";
$idarray = explode("/",$listl2[2]);
for ($i=0; $i < sizeof($idarray); $i++) {
if (preg_match("@^([0-9]+)$@",$idarray[$i])) {
$id = $idarray[$i];
break;
}
}
$result3 = mysql_query("select id from ".$prefix."_boutique where id='$id'");
$nbre = mysql_num_rows($result3);
if ($nbre > 0) {
mysql_query("UPDATE ".$prefix."_boutique set modele='$modele', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]' where id='$id'");
}else if ($modele != "") {
mysql_query("INSERT INTO ".$prefix."_boutique set modele='$modele', id='$id', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]'");
}
}
$compteur=0;
$result1 = mysql_query("select famille from ".$prefix."_boutique group by famille order by famille");
while (list($famille) = mysql_fetch_row($result1)) {
$compteur++;
mysql_query("UPDATE ".$prefix."_boutique set famille_id='$compteur' where famille='$famille'");
}
$compteur=0;
$result1 = mysql_query("select marque from ".$prefix."_boutique group by marque order by marque");
while (list($marque) = mysql_fetch_row($result1)) {
$compteur++;
mysql_query("UPDATE ".$prefix."_boutique set marque_id='$compteur' where marque='$marque'");
}
$result3 = mysql_query("select id from ".$prefix."_boutique where id='$id'");
$nbre = mysql_num_rows($result3);
if ($nbre > 0) {
mysql_query("UPDATE ".$prefix."_boutique set modele='$modele', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]' where id='$id'");
}else if ($modele != "") {
mysql_query("INSERT INTO ".$prefix."_boutique set modele='$modele', id='$id', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]'");
}
Oui, en effet, c'est de l'optimisation, mais je ne pense pas que ce soit le problème d'origine. C'est un serveur dédié, donc personne d'autre... et au niveau processeur je suis à peine à 25% de CPU durant les pics...zeb a dit:Quand on regarde le code de ton script vite fait c'est en effet assez anodin seulement tu as dès le départ deux boucles imbriquées (ligne 5 et 23) qui en plus d'exécuter des expressions régulières (c'est pas forcement léger de plus tu semble shooter un contenu fixe ce qui est pas le meilleur moyen), font des requêtes d'update ou d'insert.
A ce stade je tenterait une concaténation de la partie SQL pour ne la faire qu'en une fois a la sortie des boucles (je me connecte je passe ma requête concaténé je ferme je passe a la suite).
[/code]
Ok, mais je ne suis pas un pro de la concaténation...
La table fait 3287 lignesEnsuite tu repart dans deux itérations d'update qui sont loin d'être légère si la table boutique est un peu musclée. Là encore tu pourrait envisager de regrouper les update afin d'éviter de multiples accès a la base.
Toujours dans ces deux dernière boucles tu utilise un group by je pense qu'il est impossible de s'en passer mais sachant que tu traite tous les champs "famille" est il necessaire de demander une sortie ordonnée (order by famille) ? ce dernier traitement SQL si il peut être évité te fera peut être gagner des ressources.
Oui, en effet, je peux peut être me passer du tri sur cette requête...
Environ 10 000Pour se faire une idée de l'impact SQL de ce script il faudrait connaitre le nombre de lignes du fichier product que tu parse.
Oui, c'est exactement ça, je teste juste si il est présent.Après je note une opération qui me semble "pas pertinente" ligne 29 :
Code:$result3 = mysql_query("select id from ".$prefix."_boutique where id='$id'"); $nbre = mysql_num_rows($result3); if ($nbre > 0) { mysql_query("UPDATE ".$prefix."_boutique set modele='$modele', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]' where id='$id'"); }else if ($modele != "") { mysql_query("INSERT INTO ".$prefix."_boutique set modele='$modele', id='$id', description='$description', famille='$famille', famille_id='$famille_id', marque='$marque', marque_id='$marque_id', prix='$listl2[3]', adresse='$listl2[2]', photo='$listl2[9]'"); }
select id from ".$prefix."_boutique where id='$id' semble vouloir dire donne moi l'id de boutique don l'id est X bref donne moi truc qui est truc :
1/ tu connais donc l'id as tu besoin de faire une requête ?
le test qui suit me laisse penser ($nbre > 0) que par cette requête tu détermine si l'id en question est présent ou pas. s'il ne l'est pas ($nbre = 0) alors tu fait une insertion sinon un update.
C'est quoi la syntaxe "en cas d'erreur" pour la requête MySQL?En imaginant que l'id est unique, perso je ferait un insert dans tous les cas (qui retournera une erreur si l'id existe déjà -> normal) et dans ce cas (erreur) je ferais un update ... A chaque itération tu gagne donc la requête de test et dans le cas ou l'id existe tu fait une seconde requête donc pour chaque itération c'est une ou deux requête au lieu de deux systématiquement avec l'utilisation de mysql_num_rows en moins ce qui n'est pas rien.
Note que tu peux aussi inverser la logique en forçant l'update et en faisant l'insert sur le cas en erreur (l'erreur se produira alors lors de l'update d'un record qui n'existe pas encore). C'est la structure des datas et la fréquence des nouveautés qui doit dicter le choix. Si tu as beaucoup de nouveaux id par rapport aux existant ti insert en premier si c'est l'inverse (ce qui serait plus logique) tu update en priorité et tu insert en cas d'erreur.
Voila qque pistes qui ne règlent pas le souci du 9 de chaque mois mais c'est peut être tout simplement (si tu n'est pas sur un dédié) qu'un autre utilisateur exécute une tache aussi a cette date et heure (essaie de le décaler de 10 mn pour voir sans pour autant supprimer la tâche)
je ne suis pas un pro de la concaténation
$requeteGlobal = '';
while(condition){
(...)
$marequete = 'truc machin; ';
$requeteGlobal .= $marequete; // concaténation de chaque requête unitaire dans une requête globale
(...)
}
mysql-query($requeteGlobal);
Mazette !!! ça fait un bilan carbone pas léger ... T'imagine que ton code fait pas moins de 20 000 requêtes dans la première série de boucle ! moi à sa place je te répond "t'as vue la vierge ?" (humour) même si php et mysql sont optimisés pour atténuer ce genre de comportement tu est limite je pense.Environ 10 000
Je ne l'ai pas en tête (mis a part le OR DIE) car j'évite ce genre de situation mais prend le temps de choper le code retourné vers php par mysql sur une table de test et tu sera vite fixé. et regarde iciC'est quoi la syntaxe "en cas d'erreur" pour la requête MySQL?
A l'origine tes table n'étaient pas si importantes et ton fichier surement pas aussi ... C'est de l'effet cumulatif a mon avis.mais je ne pense pas que ce soit le problème d'origine
mouais je sais pas si c'est un détail significatif car c'est pas tant le "calcul" donc les spé intrinsèques du processeur qui sont sollicités que l'échange de données vers la base ce qui ne demande pas forcement de gros calculs mais en revanche de part le volume peut demander du temps et là l'effet pourrait être le même.au niveau processeur je suis à peine à 25% de CPU durant les pics...
Mazette !!! ça fait un bilan carbone pas léger ... T'imagine que ton code fait pas moins de 20 000 requêtes dans la première série de boucle ! moi à sa place je te répond "t'as vue la vierge ?" (humour) même si php et mysql sont optimisés pour atténuer ce genre de comportement tu est limite je pense.
Ok, je vais regarder merciJe ne l'ai pas en tête (mis a part le OR DIE) car j'évite ce genre de situation mais prend le temps de choper le code retourné vers php par mysql sur une table de test et tu sera vite fixé. et regarde ici
Sincèrement je ne pense pas, il y a toujours eu énormément d'articles, et les mises à jour sont très légères (une 15aine d'article en plus tous les 2 mois)A l'origine tes table n'étaient pas si importantes et ton fichier surement pas aussi ... C'est de l'effet cumulatif a mon avis.
Tous les autres graphes ne semblent pas montrer une souffrance quelconque du serveur. Mais je n'arrive pas à avoir les requêtes I/O sous munin, donc je ne ne sais pas ce que ça donne de ce côté là...mouais je sais pas si c'est un détail significatif car c'est pas tant le "calcul" donc les spé intrinsèques du processeur qui sont sollicités que l'échange de données vers la base ce qui ne demande pas forcement de gros calculs mais en revanche de part le volume peut demander du temps et là l'effet pourrait être le même.
As tu regardé si ce script fautif était pas le seul a taper dans cette base .... auquel cas tu pourrait recentrer le souci sur cette base.Recif a dit:j'en ai 5 différents sur 5 bases/tables différentes
Oui j'ai vue aussi, ça me saoule d'autant que passer de fonctions natives bien rodées a une classe objet genre PDO de mémoire, ça ne garanti rien de mieux si ce n'est plus de conso mémoire et un code plus récent donc moins fiable...Recif a dit:plus l'utiliser à partir de php 5.5! Je ne suis pas à cette version, mais pour le futur c'est aps top. D'ailleurs un paquet de scripts seraient obsolètes si je devais passer en 5.5. C'est vraiment pénible ces incompatibilités dans les différentes versions de php! :-((