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

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

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

Merci ;)
 
WRInaute discret
tu peux même encore aller plus vite en te passant du mysql_fetch_array

Code:
$query   = "SELECT count(id) as compte from table";
$res = mysql_query($query);
$total = mysql_result($res, '0', 'compte');
 
WRInaute occasionnel
Vous me confirmez que count(*) est plus rapide que count(id) ? :?
Vous êtes bien tous d'accord là-dessus ? Spoutnik, reconnais-tu ton erreur? ;)
 
WRInaute occasionnel
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
 
WRInaute passionné
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(*)
 
WRInaute occasionnel
spidetra a dit:
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 :)
 
WRInaute impliqué
Faites des bench :)

Je propose ca :

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

Il faudrait tester tout ca :D
 
WRInaute passionné
STFprod a dit:
spidetra a dit:
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 :)
On est d'accord :)

Ma dissertation était juste là pour faire une distinction entre les 2 formes existantes de count(). Je ne suis pas sur qu'elle soit connue de tout le monde.

En fait, je ne m'insurge pas plus que ça ( c'est pas tellement important
:) ).
 
WRInaute passionné
mowmow a dit:
spidetra a dit:
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/

Oui, je sais je connais ce bench.
ça ne m'empêche pas d'utiliser systématiquement les doubles quotes.
 
WRInaute passionné
mowmow a dit:
Hélas c'est le problème, les programmeurs PHP apprennent sur des sites utilisant des double ^^
en ce qui me concerne, c'est un choix volontaire. Je t'explique pourquoi en MP, histoire de pas trop polluer le forum.
 
Discussions similaires
Haut