[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.
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:
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()".
Test du script avec concaténation dans une variable
nextdev, le script avec concaténation dans une variable donne un temps de 11 millièmes de secondes par mysql_query().
C'est à dire beaucoup moins que le mysql_query précédé du echo...(40 millisecondes), mais encore un tout petit plus que le mysql_query() exécuté seul à l'intérieur d'une itération (8 millisecondes dans ce cas).
J'ai fait le test suivant : exécution en boucle (par une fonction récursive) de plusieurs mysql_query(). Dans ce cas, xdebug donne un temps de traitement de 40 millisecondes pour le premier, puis de 8 millisecondes pour tous les suivants.
La question est de savoir à quoi est imputable la multiplication par 5 du temps de traitement du premier mysql_query() ?
Est-ce une mauvaise imputation du temps de traitement par xdebug, et si oui, à quoi faut-il imputer ces 4 ms ?
Si non, pourquoi le temps d'exécution du mysql_query() dépend-il des instructions précédentes (dans les exemples de cette discussion : 40 ms si echo ou fonction récursive, 8 ms dans une boucle for, 11 ms après une affectation à une variable) ?