[PHP/SQL] Quel est le plus rapide pour compter les rangées ?

Consultez la formation au référencement naturel Google de WebRankInfo / Ranking Metrics


SuperPJ
WRInaute passionné
WRInaute passionné
 
Messages: 513
Inscription: Sam Jan 15, 2005 5:44

[PHP/SQL] Quel est le plus rapide pour compter les rangées ?

Message le Dim Oct 30, 2005 17:14

Quel est selon vous le plus rapide pour compter les rangées entre :

Code: Tout sélectionner
$sql = "SELECT COUNT(*) AS count FROM table ";
$res = mysql_query( $sql );
$val = mysql_fetch_array( $res, MYSQL_ASSOC );
$colonnes = $val['count'];
ou :
Code: Tout sélectionner
$sql = "SELECT * FROM table";
$res = mysql_query( $sql );
$colonnes = mysql_num_rows($res);


Merci ;)

spidetra
WRInaute accro
WRInaute accro
 
Messages: 1500
Inscription: Lun Juil 07, 2003 13:06

Message le Dim Oct 30, 2005 17:17

count(*)


SuperPJ
WRInaute passionné
WRInaute passionné
 
Messages: 513
Inscription: Sam Jan 15, 2005 5:44

Message le Dim Oct 30, 2005 17:22

Merci chef :D c'est aussi ce que je me disais :P


spout
WRInaute accro
WRInaute accro
 
Messages: 1320
Inscription: Mer Mai 14, 2003 11:05

Message le Dim Oct 30, 2005 18:18

spidetra a écrit:count(*)


Encore plus rapide (ou du moins plus propre):
COUNT(id)


SuperPJ
WRInaute passionné
WRInaute passionné
 
Messages: 513
Inscription: Sam Jan 15, 2005 5:44

Message le Dim Oct 30, 2005 18:36

Merci spoutnik ;)

tigrou
WRInaute discret
WRInaute discret
 
Messages: 83
Inscription: Dim Fév 29, 2004 18:18

Message le Dim Oct 30, 2005 20:51

tu peux même encore aller plus vite en te passant du mysql_fetch_array

Code: Tout sélectionner
$query   = "SELECT count(id) as compte from table";
$res = mysql_query($query);
$total = mysql_result($res, '0', 'compte');


STFprod
WRInaute passionné
WRInaute passionné
 
Messages: 627
Inscription: Mer Jan 14, 2004 7:39

Message le Dim Oct 30, 2005 22:23

spoutnik a écrit:
spidetra a écrit:count(*)


Encore plus rapide (ou du moins plus propre):
COUNT(id)


ah non, c'est bel et bien count(*) qui est plus rapide. A quoi bon compter le nombre d'id, alors qu'on peut calculer le nombre de lignes ?


Digit
WRInaute passionné
WRInaute passionné
 
Messages: 613
Inscription: Ven Avr 18, 2003 0:19

Message le Dim Oct 30, 2005 22:34

plus généralement, quel que soit le SGBD, count(1) est plus rapide que count(id)


SuperPJ
WRInaute passionné
WRInaute passionné
 
Messages: 513
Inscription: Sam Jan 15, 2005 5:44

Message le Dim Oct 30, 2005 22:48

Vous me confirmez que count(*) est plus rapide que count(id) ? :?
Vous êtes bien tous d'accord là-dessus ? Spoutnik, reconnais-tu ton erreur? ;)

squawk
WRInaute accro
WRInaute accro
 
Messages: 5985
Inscription: Lun Mar 22, 2004 19:45

Message le Dim Oct 30, 2005 23:18

sur à 100% :wink:


Digit
WRInaute passionné
WRInaute passionné
 
Messages: 613
Inscription: Ven Avr 18, 2003 0:19

Message le Lun Oct 31, 2005 0:53

Je ne confirme pas.
S'il s'avère que la requête contient une clause where, il n'y a pas l'utilisation en interne de mysql de la zone de stockage de cette valeur (le moteur innodb réserve une petite zone de données dans les structures de tables pour y mémoriser le nb d'enregistrements) et la requete doit alors parcourir toutes les lignes (d'où un besoin d'index pour réduire le calcul)
J'ai précisé que count(1) est le plus rapide car aucune donnée de la table (aucune valeur de champs) n'est récupérée. un count(id) lirait toutes les valeurs du champs.
Le count(*) a de forte chances de lire tous les champs tandis que le count(1) n'en lira aucun, ce doit donc être théoriquement plus rapide

spidetra
WRInaute accro
WRInaute accro
 
Messages: 1500
Inscription: Lun Juil 07, 2003 13:06

Message le Lun Oct 31, 2005 10:38

Je suis surpris qu'un simple count(*) entraîne un tel débat.

La comparaison count(*)/count(id) en terme de performance me paraît aussi inutile que la comparaison double quote/simple quote en PHP.

Ce n'est pas là que vous devez fournir vos efforts pour améliorer significativement les performances de votre système. Les gains, s'ils existent, sont minimes et insignifiants.

S'il existe un écart entre count(*) et count(id), combien de fois faut-il exécuter la requête pour avoir un gain d'une seconde ?
Plusieurs dizaines de milliers de fois, centaines de milliers de fois ?

Par contre, cela me gêne un peu plus, non pas en terme de performance, mais en terme de compréhension de la foncion d'aggrégation count().

La fonction count a deux format :
- cardinalité
- expression

1. Cardinalité : La cardinalité d'une table, c'est son nombre de ligne.
L'opérateur cardinalité de la fonction count est : *
Donc pour compter le nombre de ligne d'une table, sa cardinalité, la bonne forme est toujours : count(*).
Si on remplace count(*) par count(id), dans la mesure où id est la clé primaire. Nous obtenons exactement le même résultat. A tel point, que si le moteur sql est bien implémenté, il effectue automatiquement un count(*) à la place d'un count(id).

Le * du count(*), n'as pas la même signification que le * du select *.
Donc, non, quand on fait un count(*), on ne récupére pas tout les champs de la table. On dit juste au moteur SQL : renvoie moi la cardinalité de la table.


2. Compter une expression : count([ALL|DISTINCT] expression)
Lorsque l'on compte une expression on compte toutes les valeurs connues de l'expression.
Ce qui veut dire :
- les nulls ont été éliminé avant le comptage, et count renvoie 0 si aucune ligne n'a été trouvée.
- count(DISTINCT expression ) : les nulls ont été supprimmé avant comptage, et la table a été dédoublonné.

Evidemment, lorsque l'on fait un count(id), id étant la clé primaire, on obtient exactement le même résultat que pour un count(*).
- une clé primaire n'accepte pas la valeur null
- une clé primaire pas de doublons.

Il n'est pas plus propre, ou moins propre, d'utiliser count(id) à la place de count(*)) => on ne compte pas la même chose.

Conclusion :
- chaque fois que tu veux calculer une cardinalité ( nbr de ligne ) : utilise count(*)
- chaque fois que tu veux compter une expression : utilise count(expression).

Tout ça pour en revenir à ma première réponse laconique :

count(*)


STFprod
WRInaute passionné
WRInaute passionné
 
Messages: 627
Inscription: Mer Jan 14, 2004 7:39

Message le Lun Oct 31, 2005 10:45

spidetra a écrit:Je suis surpris qu'un simple count(*) entraîne un tel débat.

La comparaison count(*)/count(id) en terme de performance me paraît aussi inutile que la comparaison double quote/simple quote en PHP.

Tu t'insurges sur le fait qu'un tel débat soit stérile et fait pour départager 2 méthodes, et c'est toi qui nous fait une dissertation surle principe de base de données, pour terminer par : c'est count(*)...

Finalement, c'est ce qu'on a dit depuis le début :-)


mowmow
WRInaute passionné
WRInaute passionné
 
Messages: 975
Inscription: Mer Nov 03, 2004 9:40

Message le Lun Oct 31, 2005 10:45

Faites des bench :)

Je propose ca :

$sql = mysql_query('SELECT 1 FROM table');
$count = mysql_num_rows($sql);

Il faudrait tester tout ca :D


mowmow
WRInaute passionné
WRInaute passionné
 
Messages: 975
Inscription: Mer Nov 03, 2004 9:40

Message le Lun Oct 31, 2005 10:49

spidetra a écrit:La comparaison count(*)/count(id) en terme de performance me paraît aussi inutile que la comparaison double quote/simple quote en PHP.


Il n'y a aucun débat à faire sur les double/simple quotes, il a été prouvé que les simple quotes sont plus rapides :

http://www.estvideo.com/dew/pages/phpbench/

[PHP/SQL] Quel est le plus rapide pour compter les rangées ?

Formation recommandée sur ce thème :

Formation Référencement naturel Google : apprenez une méthode efficace pour optimiser à fond le référencement naturel dans Google de façon durable... Formation animée par Olivier Duffez et Fabien Facériès, experts en référencement naturel.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités