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 :

Calcul d'une somme dans une boucle VERSUS Calcul via la fonction MySQL SUM


Sujet :

PHP & Base de données

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Calcul d'une somme dans une boucle VERSUS Calcul via la fonction MySQL SUM
    Tout est dans le titre... Je souhaite présenter des données extraites de la base de données accompagnés de leur totaux respectifs. Je me pose alors des questions sur la performance pour le calcul de ses sommes. Quel est la méthode la plus performante ?

    Je vois deux pistes possibles.

    1 - Calculer la somme dans une boucle après avoir récupérer les données d'une requête SQL.

    2 - Calculer la somme à l'aide de la fonction MySQL SUM


    Afin d'illustrer mon propos, un p'tit exemple


    //--------[1er Méthode]--------\\
    On effectue une seul requête SQL pour récupérer les informations. Le calcul de la somme se fait de manière itérative dans le parcours du curseur (boucle while).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $sql = 'SELECT id, valeur1, valeur2 FROM table';
    $query = mysql_query($sql); 
    $sumValeur1 = 0;$sumValeur2 = 0;
    echo "<pre>";
    echo "id | valeur1 | valeur2<br/>";
    while($resultat = mysql_fetch_object($query)) {
       echo $resultat->id."|".$resultat->valeur1."|".$resultat->valeur2."<br/>";
       $sumValeur1 += $sumValeur1 + $resultat->valeur1;
       $sumValeur2 += $sumValeur2 + $resultat->valeur2;
    }
    echo "total | ".$sumValeur1."|".$sumValeur2;
    echo "</pre>";
    //--------[2nd Méthode]--------\\
    Dans ce cas, on effectue deux requêtes SQL, une première pour récupérer les données et une seconde pour calculer la somme avec la fonction MySQL SUM.

    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
    $sql = 'SELECT id, valeur1, valeur2 FROM table';
    $query = mysql_query($sql);
    echo "<pre>";
    echo "id | valeur1 | valeur2<br/>";
    while($resultat = mysql_fetch_object($query)) {
       echo $resultat->id."|".$resultat->valeur1."|".$resultat->valeur2."<br/>";
    }
     
    $sqlSomme = 'SELECT 
      SUM(valeur1) as sumValeur1, 
      SUM(valeur2) as sumValeur2 
    FROM table';
    $querySomme = mysql_query($sqlSomme);
    $resultatSomme = mysql_fetch_object($querySomme);
    echo "total | ".$resultatSomme->sumValeur1."|".$resultatSomme->sumValeur2;
    echo "</pre>";
    Quel méthode est la plus performante ?
    Il est évident que si la table ne contient que 20 enregistrements, la question ne se pose même pas...

    Si vous avez des pistes, chuis preneur ^^
    Merci d'avance

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    MySQL sera toujours plus rapide que PHP
    y'a avais un article la dessus faudrait que je le retrouve

    EDIT : Trouvé
    http://www.onextrapixel.com/2010/06/...l-performance/


  3. #3
    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
    Points : 44 155
    Points
    44 155
    Par défaut
    La page que tu donnes montre le contraire.

    Si on reprend les temps donnés dans la page, la méthode 1 mettrait dans les 5, la méthode 2 mettrait dans les 7s.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par sabotage Voir le message
    La page que tu donnes montre le contraire.

    Si on reprend les temps donnés dans la page, la méthode 1 mettrait dans les 5, la méthode 2 mettrait dans les 7s.
    on doit pas lire de la même façon, tu les vois ou tes chiffres ?

  5. #5
    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
    Points : 44 155
    Points
    44 155
    Par défaut
    La méthode 1 c'est le cas "When PHP Calculates The Average" : 5s.

    La méthode 2 c'est le cas "When MySQL Calculates The Average" : 2s avec en plus la meme requête que "When PHP Calculates The Average" sans la partie calculée.
    Donc effectivement ca ne fait pas 5s+2s mais 2 + quelque chose entre 0 et 5s.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par sabotage Voir le message
    La méthode 1 c'est le cas "When PHP Calculates The Average" : 5s.

    La méthode 2 c'est le cas "When MySQL Calculates The Average" : 2s avec en plus la meme requête que "When PHP Calculates The Average" sans la partie calculée.
    Donc effectivement ca ne fait pas 5s+2s mais 2 + quelque chose entre 0 et 5s.
    y'a pas de + quelque chose, le microtime se fait au même endroit, faut tout lire

    Test 1 - Calculating an Average Score
    Using MySQL's AVG() function was 2.64 times faster than the equivalent PHP code

    Test 2 - Formatting a Date
    So for this instance MySQL was 4.76 times faster than the PHP equivalent.

    In Conclusion
    MySQL was up to 5.7 times faster than PHP, this was for TEN THOUSAND runs of the same code.

  7. #7
    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
    Points : 44 155
    Points
    44 155
    Par défaut
    Ba non, le test "When MySQL Calculates The Average" ne correspond pas a la methode 2, il lui manque la lecture de tous les enregistrements.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Ba non, le test "When MySQL Calculates The Average" ne correspond pas a la methode 2, il lui manque la lecture de tous les enregistrements.
    quelles enregistrements ? SELECT AVG retourne qu'une ligne... le résultat

  9. #9
    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
    Points : 44 155
    Points
    44 155
    Par défaut
    Justement ce n'est pas seulement ça que fait 2o1oo : il affiche aussi toutes les valeurs.

    Pour répondre il faudrait donc savoir ce qui prend du temps à PHP : le calcul ou la lecture des lignes, ou equitablement les deux peut être.
    Les résultats ne sont pas non plus forcemment linéaire.

    Dans un cas comme ça, je suis un peu dans l'idée "tant que j'y suis autant ..." c'est à dire puisque j'ai déjà toutes les données dans les mains, je ne refais pas une requête.
    Après ca se chronomètre.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Justement ce n'est pas seulement ça que fait 2o1oo : il affiche aussi toutes les valeurs.

    Pour répondre il faudrait donc savoir ce qui prend du temps à PHP : le calcul ou la lecture des lignes, ou equitablement les deux peut être.
    Les résultats ne sont pas non plus forcemment linéaire.

    Dans un cas comme ça, je suis un peu dans l'idée "tant que j'y suis autant ..." c'est à dire puisque j'ai déjà toutes les données dans les mains, je ne refais pas une requête.
    Après ca se chronomètre.
    je vois ce que tu veux dire, et malgré les apparences (2 requêtes, chercher le résultat), prendra moins de temps. On pourrais même gagné du temps en faisant une requête multiples

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Déjà merci de se pencher sur cette question...

    Pour répondre il faudrait donc savoir ce qui prend du temps à PHP : le calcul ou la lecture des lignes, ou équitablement les deux peut être.
    Les résultats ne sont pas non plus forcemment linéaire.

    Dans un cas comme ça, je suis un peu dans l'idée "tant que j'y suis autant ..." c'est à dire puisque j'ai déjà toutes les données dans les mains, je ne refais pas une requête.Après ca se chronomètre.
    Exactement, comme on souhaite afficher les résultats en même temps que les totaux... "tant que je suis dans la boucle while autant calculer les sommes en même temps"... mais dans ce cas quel est son coût. On peut être déjà sur que son coût dépendra du nombre d'enregistrement. Plus il y aura d'enregistrement, plus le temps de lecture de la boucle sera important.

    je vois ce que tu veux dire, et malgré les apparences (2 requêtes, chercher le résultat), prendra moins de temps. On pourrais même gagné du temps en faisant une requête multiples
    Je ne suis pas sur qu'une requête multiple soit plus efficace. Imagines que tu as 100.000 enregistrement dans la table, si tu rajoutes dans une requête multiple les totaux à la fin tu vas remonter la SOMME pour chaque ligne autrement dit 99.999 de fois de trop... Ces données transitent du SGBD -> Serveur d'application web -> Poste client pour rien... Il vaut mieux faire deux requêtes : une première pour récupérer les données et une seconde pour calculer la somme, évidemment on évite de fermer la connexion entre les deux requêtes..


    Les impératifs sont :
    - Afficher tout les résultats (JQgrid powa ^^ par exemple)
    - Afficher les totaux en footer
    - Choisir la méthode la plus performante pour calculer les totaux

    Remarque, on pourrait faire les calcul côté client en JavaScript... mais bon la je perds en accessibilité et j'aime pas çà.

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par 2o1oo Voir le message
    Je ne suis pas sur qu'une requête multiple soit plus efficace. Imagines que tu as 100.000 enregistrement dans la table, si tu rajoutes dans une requête multiple les totaux à la fin tu vas remonter la SOMME pour chaque ligne autrement dit 99.999 de fois de trop... Ces données transitent du SGBD -> Serveur d'application web -> Poste client pour rien... Il vaut mieux faire deux requêtes : une première pour récupérer les données et une seconde pour calculer la somme, évidemment on évite de fermer la connexion entre les deux requêtes..
    c'est pas ça une requête multiple...

    2 requêtes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    -   SELECT id FROM blabla WHERE marchin = truc;
    -  SELECT COUNT(id) FROM blabla WHERE marchin = truc GROUP BY toto;
    1 requête multiple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -   SELECT id FROM blabla WHERE marchin = truc; SELECT COUNT(id) FROM blabla WHERE marchin = truc GROUP BY toto;
    la requête multiple sera toujours rapide

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Ok je n'avais pas bien compris le sens de requête multiple... il s'agit de l'envoie de plusieurs instructions en SQL au SGBD en une seule fois...

    J'avais imaginé que tu parlais d'une requête de type

    SELECT id, valeur1, valeur2, SUM(valeur1) as s1, SUM(valeur2) as s2
    FROM table
    qui pose les difficultés cité plus haut...

  14. #14
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par 2o1oo Voir le message
    Ok je n'avais pas bien compris le sens de requête multiple... il s'agit de l'envoie de plusieurs instructions en SQL au SGBD en une seule fois...

    J'avais imaginé que tu parlais d'une requête de type



    qui pose les difficultés cité plus haut...
    en faisant des bench, au bout de 500 lignes ca devient plus rapide, mais ca suis de très près la méthode 1

  15. #15
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut
    Une chose à considérer...
    Je ne suis pas grand spécialiste de la question mais d'après ce que j'ai pu lire ici ou là, un SGBD travaille en mémoire vive et garde des statistiques sur ce qu'il a déjà fait.

    Si le comptage est appelé souvent avec une table dont le contenu n'a pas changé depuis le dernier appel, il est peut-être possible que le SGBD puise dans ses statistiques et ne relance pas la requête de comptage, ce qui sera beaucoup plus rapide avec un grand nombre de lignes. Alors que le comptage sera systématiquement relancé à chaque appel du programme PHP.

    Si le boulot est à faire sur un petit nombre de lignes, le temps passé sera probablement très voisin entre les deux méthodes. Si par contre il y a beaucoup de lignes à traiter, le SQL sera sûrement plus rapide que PHP. Les SGBD sont quand même faits pour traiter de gros volumes de données.

    Bref, il faut tester avec une grosse table.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Bon voila des p'tits tests sur ces deux approches...


    1 - La table de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE `table_test` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `valeur1` int(10) unsigned default NULL,
      `valeur2` int(10) unsigned default NULL,
      `valeur3` smallint(5) unsigned NOT NULL default '0',
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

    2 - Pour insérer des données aléatoires dans cette table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $nbEnregistrement = 50000;
    $sql_insert = "INSERT INTO `table_test_500000` 
    (`valeur1`, `valeur2`, `valeur3`) VALUES ";
    for($i=1;$i<=$nbEnregistrement;$i++) {
       $sql_insert .= "(".rand(1,100).", ".rand(1,100).", ".rand(1,100).")";
       if($i!=$nbEnregistrement) {
          $sql_insert .= ", ";
       }
    }

    3 - Première méthode (calcul de la somme dans la boucle) :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    function methode1_calculSommeDansBoucle($table) {
    	ob_start();
    	$start_method1 = microtime(true);
     
    	$idConnect = mysql_connect(CST_BDD_HOSTNAME,CST_BDD_LOGIN,CST_BDD_PASS);
    	$bddSelect = mysql_select_db(CST_BDD_DATABASE,$idConnect);
    	$sqlSelect = 'SELECT id, valeur1, valeur2, valeur3 FROM '.$table;
    	$reqSelect = mysql_query($sqlSelect,$idConnect);
    	$sumValeur1 = 0; 
    	$sumValeur2 = 0; 
    	$sumValeur3 = 0;
    	$table_method1 = 
    	"<table>
    		<thead>
    			<tr>
    				<th colspan='4'>On a ".mysql_num_rows($reqSelect)." enregistrements récupères dans table_test</th>
    			</tr>		
    			<tr>
    				<th>id</th><th>valeur1</th><th>valeur2</th><th>valeur3</th>
    			</tr>
    		</thead>
    		<tbody style='height:300px;overflow-x:hidden;overflow-y:auto;'>";
    		while($resultat = mysql_fetch_object($reqSelect)) {
    			$table_method1 .= "<tr>
    				<td>".$resultat->id."</td>
    				<td>".$resultat->valeur1."</td>
    				<td>".$resultat->valeur2."</td>
    				<td>".$resultat->valeur3."</td>
    			</tr>";
    			$sumValeur1 = $sumValeur1 + $resultat->valeur1;
    			$sumValeur2 = $sumValeur2 + $resultat->valeur2;
    			$sumValeur3 = $sumValeur3 + $resultat->valeur3;
    		}
    	$table_method1 .= "</tbody>
    		<tfoot style='font-weight:bold;'>
    			<tr>
    				<td>TOTAL</td>
    				<td>".$sumValeur1."</td>
    				<td>".$sumValeur2."</td>
    				<td>".$sumValeur3."</td>
    			</tr>
    		</tfoot>
    	</table>";
    	mysql_free_result($reqSelect);
    	mysql_close($idConnect);
     
    	$end_method1 = microtime(true);
    	ob_end_clean(); 
    	return ($end_method1 - $start_method1);
    }

    4 - Seconde méthode (calcul de la somme avec SUM MySQL) :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    function methode2_calculSommeDansMysql($table) {
    	ob_start();
    	$start_method2 = microtime(true);
     
    	$idConnect = mysql_connect(CST_BDD_HOSTNAME,CST_BDD_LOGIN,CST_BDD_PASS);
    	$bddSelect = mysql_select_db(CST_BDD_DATABASE,$idConnect);
    	$sqlSelect = 'SELECT id, valeur1, valeur2, valeur3 FROM '.$table;
    	$sqlSomme = 'SELECT SUM(valeur1) as sum1, SUM(valeur2) as sum2, SUM(valeur3) as sum3 FROM '.$table;
    	$reqSelect = mysql_query($sqlSelect,$idConnect);
    	$reqSomme = mysql_query($sqlSomme,$idConnect);
    	$resSomme = mysql_fetch_object($reqSomme);
    	$table_method2 = 
    	"<table>
    		<thead>
    			<tr>
    				<th colspan='4'>On a ".mysql_num_rows($reqSelect)." enregistrements récupères dans ".$table."</th>
    			</tr>		
    			<tr>
    				<th>id</th><th>valeur1</th><th>valeur2</th><th>valeur3</th>
    			</tr>
    		</thead>
    		<tbody style='height:300px;overflow-x:hidden;overflow-y:auto;'>";
    		while($resSelect = mysql_fetch_object($reqSelect)) {
    			$table_method2 .= "<tr>
    				<td>".$resSelect->id."</td>
    				<td>".$resSelect->valeur1."</td>
    				<td>".$resSelect->valeur2."</td>
    				<td>".$resSelect->valeur3."</td>
    			</tr>";
    		}
    	$table_method2 .= "</tbody>
    		<tfoot style='font-weight:bold;'>
    			<tr>
    				<td>TOTAL</td>
    				<td>".$resSomme->sum1."</td>
    				<td>".$resSomme->sum2."</td>
    				<td>".$resSomme->sum3."</td>
    			</tr>
    		</tfoot>
    	</table>";
    	mysql_free_result($reqSelect);
    	mysql_close($idConnect);
     
    	$end_method2 = microtime(true);
    	ob_end_clean(); 
    	return ($end_method2 - $start_method2);
    }

    5 - Résultat sortie CSV :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    function bench2CSV($table, $nbTest, $nbEnregistrement) {
    	$str = "";
    	$sumtimeExec_methode1 = 0;
    	$sumtimeExec_methode2 = 0;
    	echo "<h3>---[ Start Bench ".$table." avec ".$nbTest." tests ]---</h3>";
    	echo "---[ Test : ";
    	ob_flush();
    	flush();
    	for($i=0;$i<$nbTest;$i++) {
    		set_time_limit(0);
    		$timeExec_methode1 = round(methode1_calculSommeDansBoucle($table),5);
    		$timeExec_methode2 = round(methode2_calculSommeDansMysql($table),5);
    		$sumtimeExec_methode1 = $sumtimeExec_methode1 + $timeExec_methode1;
    		$sumtimeExec_methode2 = $sumtimeExec_methode2 + $timeExec_methode2;		
    		$percent = round(($timeExec_methode2/$timeExec_methode1)*100 - 100,2);
    		$str .= $nbEnregistrement.",".$nbTest.",".($i+1).",".$timeExec_methode1.",".$timeExec_methode2.",".$percent."\n";
    		echo " ".($i+1).", ";
    		ob_flush();
    		flush();		
    	}
    	echo " ]------<br/>";
    	echo "---[ End Bench :]---";
    	ob_flush();
    	flush();	
    	return $str;
    }

    6 - Résultat sortie HTML :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    function bench2HTML($table, $nbTest) {
    	$stringOut = "<table>
    	<thead>
    		<tr>
    			<th>Iteration</th>
    			<th>Time Method1<br/>(somme Loop)</th>
    			<th>Time Method2<br/>(somme Mysql)</th>
    			<th>Time Diff</th>
    		</tr>
    	</thead>";
     
    	$sumtimeExec_methode1 = 0;
    	$sumtimeExec_methode2 = 0;
    	for($i=0;$i<$nbTest;$i++) {
    		set_time_limit(0);
    		$timeExec_methode1 = round(methode1_calculSommeDansBoucle($table),5);
    		$timeExec_methode2 = round(methode2_calculSommeDansMysql($table),5);
    		$sumtimeExec_methode1 = $sumtimeExec_methode1 + $timeExec_methode1;
    		$sumtimeExec_methode2 = $sumtimeExec_methode2 + $timeExec_methode2;		
    		$percent = round(($timeExec_methode2/$timeExec_methode1)*100 - 100,2);
    		$stringOut .= "<tr><td>".$i."</td>";
    		if($timeExec_methode1<$timeExec_methode2) {
    			$stringOut .= "<td style='background-color:#ADFF9F;'>".$timeExec_methode1."</td><td>".$timeExec_methode2."</td>";
    		} else {
    			$stringOut .= "<td>".$timeExec_methode1."</td><td style='background-color:#ADFF9F;'>".$timeExec_methode2."</td>";
    		}
    		$stringOut .= "<td>".$percent." %</td></tr>";
    	}
    	$moytimeExec_methode1 = round(($sumtimeExec_methode1/$nbTest),5);
    	$moytimeExec_methode2 = round(($sumtimeExec_methode2/$nbTest),5);
    	$moypercent = round(($moytimeExec_methode2/$moytimeExec_methode1)*100 - 100,2);
     
    	$stringOut .= "</tbody><tfoot><tr><td>Moy</td>";
    	if($moytimeExec_methode1<$moytimeExec_methode2) {
    		$stringOut .= "<td style='background-color:#7FDF6F;'>".$moytimeExec_methode1."</td><td>".$moytimeExec_methode2."</td>";
    	} else {
    		$stringOut .= "<td>".$moytimeExec_methode1."</td><td style='background-color:#7FDF6F;'>".$moytimeExec_methode2."</td>";
    	}
    	$stringOut .= "<td>".$moypercent." %</td></tr></tfoot></table>";
    	return $stringOut;
    }

    7 - Résultat HTML :


    8 - Résultat CSV:
    Fichiers attachés Fichiers attachés

  17. #17
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut
    Si je lis bien tes tableaux, tu t'es fait chier pour gagner un 10ème de seconde non ?
    100 000 lignes, pour un SGBD, ce n'est pas encore énorme. Apparemment, pour PHP, ça tient encore le coup.

    Si tu peux prolonger ton test à 1 million, voire 10 millions de lignes, ça devrait être plus significatif. Peut-être même que PHP n'arrivera plus à traiter autant de données en mémoire ? Je n'en sais rien, je viens d'une époque où il fallait économiser les bits dans les programmes (processeurs 8 bits, 1 ko de mémoire vive, stockage sur cassette !)
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  18. #18
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Si je lis bien tes tableaux, tu t'es fait chier pour gagner un 10ème de seconde non ? 100 000 lignes, pour un SGBD, ce n'est pas encore énorme. Apparemment, pour PHP, ça tient encore le coup.

    Si tu peux prolonger ton test à 1 million, voire 10 millions de lignes, ça devrait être plus significatif. Peut-être même que PHP n'arrivera plus à traiter autant de données en mémoire ? Je n'en sais rien, je viens d'une époque où il fallait économiser les bits dans les programmes (processeurs 8 bits, 1 ko de mémoire vive, stockage sur cassette !)
    Si tu raisonnes pour un utilisateur unique certes le gain n'est pas notable, mais multiplie çà par 1000 utilisateurs en même temps une toute petite économie vaut quand même le coup... en plus tu le dis toi même venant d'une époque lointaine où il fallait économiser chaque bits.... en plus ca répond à ma question.

    [(Sum Loop) coûte plus cher (Sum MySQL) lorsque NbEnregistrements>1000]


    Si le comptage est appelé souvent avec une table dont le contenu n'a pas changé depuis le dernier appel, il est peut-être possible que le SGBD puise dans ses statistiques et ne relance pas la requête de comptage, ce qui sera beaucoup plus rapide avec un grand nombre de lignes. Alors que le comptage sera systématiquement relancé à chaque appel du programme PHP.
    Entièrement d'accord, l'optimiseur du SGBD peut relayer les requêtes de manière beaucoup plus rapide si la réponse est en cache... C'est un paramètre auquel je n'avais pas pensé.

    +1 pour SUM MySQL

Discussions similaires

  1. Réponses: 7
    Dernier message: 25/03/2011, 10h52
  2. Réponses: 4
    Dernier message: 15/10/2009, 13h33
  3. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  4. Envoyer une formulaire dans une page dans une Frame
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 29/06/2007, 10h13
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

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