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

PHP & Base de données Discussion :

[Script exigeant] La décomposition des traitements ne m'explique pas la durée totale


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2009
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 16
    Par défaut [Script exigeant] La décomposition des traitements ne m'explique pas la durée totale
    Bonjour,

    soit un script PHP insérant des enregistrements dans une base de données MySql. PHP calcule la valeur de trois entiers, puis insère une ligne dans la base de données. Cela est répété 18.000 fois. Au final, 18.000 enregistrements sont insérés, et l'exécution dure un quart d'heure sur ma machine.

    Durant l'exécution (en ligne de commande), le processus mysqld utilise 1 à 10% du processeur et php.exe 0 à 2% (ainsi qu'une quantité négligeable de mémoire).

    J'ai tenté de décomposer les traitements pour identifier ce qui prenait du temps.
    Résultat :
    _le script PHP seul (cad le script initial auquel l'unique ligne mysql_query a été retirée) : 1 seconde
    _18.000 enregistrements seuls (tels que ceux insérés par le script initial) : 2 minutes via un script SQL contenant 18.000 instructions "insert into"; 3 minutes via un script PHP contenant une itération sur l'instruction "insert into" répétée 18000 fois.

    En résumé :
    les calculs compliqués réalisés par PHP sont exécutés quasi-instantanément; l'insertion dans la base de valeurs aléatoires (ne relevant pas d'un calcul compliqué) via un script PHP et l'instruction MySql_query() demande environ 3 minutes.

    Pourquoi faut-il une quinzaine de minutes pour exécuter ces deux opérations ensemble ?

    Ma configuration est :
    Vista Home Basic
    PHP 5
    MySql 5.1
    Apache 2.2

    Merci.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Bonjour,

    Tu peux utiliser un outil de profiling comme xdebug pour controler precisement ce qui se passe dans ton script.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre averti
    Inscrit en
    Février 2009
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 16
    Par défaut Décomposition avec XDebug
    Merci pour l'info. J'ai donc installé XDebug.

    Je peux donc donner une description plus précise du paradoxe soulevé dans le premier post : j'ai constaté que le temps pris par l'instruction mysql_query("INSERT INTO...") dépend, avec un facteur 5, des instructions présentes "autour".
    Voyez-vous pourquoi ?

    Plus en détail, voici le test réalisé :
    Le script suivant prend 1,8 secondes sur ma machine. L'instruction MySql_Query prend alors 8 millisecondes à chacune des 200 itérations (soit 1,6 secondes au total).
    Si je décommente les deux lignes "echo...", le temps d'exécution passe à 7 ou 8 secondes.
    Le temps pris par l'instruction xdebug n'est pourtant pas très important : quelques millisecondes. D'ailleurs, si je commente l'instruction mysql_query au lieu des deux instructions echo, le temps d'éxecution tombe à 0,4 seconde. Par contre, le temps pris par l'instruction mysql_query est passé à 4 centièmes en moyenne par itération !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    	mysql_connect("localhost","USER","PASSWORD");
    	mysql_select_db("DATABASE");
    	mysql_query("TRUNCATE TABLE TEST_PERF");
     
    	echo xdebug_time_index(), " Debut Insertion \n";
    		For ($i=1;$i<=200;$i++)
    		{	
    			//echo xdebug_time_index(), " D1 \n";
    			mysql_query("INSERT INTO TEST_PERF (TEST_PERF) VALUES (1)");
    			//echo xdebug_time_index(), " D2 \n";
    		}
    	echo xdebug_time_index(), " Fin insertion \n";
    mysql_close();
     ?>
    On retrouve ainsi le facteur 5 du premier message - je passais alors de 15 minutes à 3 minutes d'exécution en supprimant toutes les instructions autour de l'itération sur "mysql_query()".

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Je ne pensais pas a ca en fait
    Dans Xdebug tu as un truc qui s'appelle "profiler"
    http://www.xdebug.org/docs/profiler

    Tu lances ton script "nature" et il te créé un rapport.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre averti
    Inscrit en
    Février 2009
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 16
    Par défaut Rapport cachegrind
    Les temps d'exécution ci-dessus sont les chiffres du profiler, que j'ai simplement vérifiés avec xdebug_time_index*.

    Pourquoi n'ai-je cependant pas donner les résultats du script "nature" ?
    Pour décomposer les temps de traitement et vous en livrer les résultats, j'ai préféré utiliser un autre script que l'initial, dont l'exécution dure un quart d'heure. Et ce pour deux raisons : pour ne pas attendre un quart d'heure les résultats des tests, et parce que le script , étant compliqué, apporterait inutilement de la complexité aux tests.

    J'ai donc voulu tester des hypothèses à partir de scripts utilisables par tout le monde. De là est issu le code du message précédent, qui permet à tout le monde de pouvoir vérifier les résultats : le fait d'ajouter une instruction qui ne mobilise guère ni CPU ni mémoire conduit à diviser par 5 la vitesse de traitement de l'instruction mysql_query(). Du moins est-ce ce que je constate via xdebug. J'aimerais bien avoir une explication.

    J'ai fait d'autres tests : j'ai voulu savoir quelles sont les instructions, qui, placées à tel endroit dans le script, vont conduire à augmenter le temps d'exécution de l'instruction mysql_query(). J'ai fait cependant trop peu de ces tests pour obtenir des résultats tangibles.

    *Au début, je ne faisais aucune confiance au profiler, car les temps sont marqués "ms" mais sont en fait des centièmes de seconde -j'utilise wincachegrind pour la restitution du fichier cachegrind.out).

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Février 2009
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 149
    Par défaut
    le temps pris par l'instruction mysql_query("INSERT INTO...") dépend, avec un facteur 5, des instructions présentes "autour".
    Tu as surtout constaté le tps que prennais a sortir le buffer via echo, en plus tu lui en met en plein millieu d'une boucle de requete sql.

    Le mieux serais la concaténation d'une variable, et derrière la boucle, l'affichage de celle ci. (voir un ob_start)

    Ressaye avec ce script, tu va encore gratter des millisecondes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?php
    mysql_connect('localhost','USER','PASSWORD');
    mysql_select_db('DATABASE');
    mysql_query('TRUNCATE TABLE TEST_PERF');
    $var = xdebug_time_index().' Debut insertion '."\n";
    $i = 0;
    while($i < 200) {	
    	$var .= xdebug_time_index().' D1 '."\n";
    	mysql_query('INSERT INTO TEST_PERF (TEST_PERF) VALUES (1)');
    	$var .= xdebug_time_index().' D2 '."\n";
    	$i++;
    	}
    $var .= xdebug_time_index().' Fin insertion '."\n";
    echo $var;
    mysql_close();
    ?>
    C'est quoi le bestiaux qui fait tourner, la config php et/ou mysql est peu etre à revoir aussi.

Discussions similaires

  1. Cout des traitement PHP
    Par emathieu13 dans le forum Langage
    Réponses: 10
    Dernier message: 11/03/2006, 23h50
  2. Script pour faire défiler des infos
    Par waddle dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 19/01/2006, 14h54
  3. Recherche script pour visualisation UML des jointures
    Par messier79 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 12/12/2005, 13h40
  4. [script SQL]comment passer des parametres a un scrip sql?
    Par la7su dans le forum Langage SQL
    Réponses: 5
    Dernier message: 23/03/2005, 10h55
  5. Réponses: 13
    Dernier message: 01/10/2004, 14h03

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