Version complète: sur le forum Webmaster Hub : Compter le nombre de lignes
Webmaster Hub > Création et exploitation de Sites Internet > Les langages du Net > SQL
skippy
Bonjour,

Je cherche (et je ne trouves pas) un moyen de compter le nombre de lignes d'une requete qui retourne plus 500 000 lignes (et ca devrait sensiblement augmenter par la suite) je travaille sur une base MySQL et je traite ca avec du PHP...

CODE
SELECT * FROM Table WHERE (conditions);


y a t il un moyen plus rapide que
CODE
mysql_num_rows($query);

CODE
SELECT COUNT(*) FROM Table WHERE (conditions);

Ces deux solutions mettent environ 20 secondes pour me retourner une réponse, le serveur n'est pas en cause ni la condition qui est tout à fait basique...
existe-t-il une solution miracle?

Par pitié, sauvez moi ...
Vincent
si rien n'est en cause, ca va être dur d'aider...

quelle est la structure de la table? sur quels champs la requete travaille-t-elle? (les champs de la conditions sont-ils dans la clé primaire ou dans un index?)
skippy
Malheuresement la condition ne s'applique pas sur la clé...
Quelqu'un aurait il une idée du volume raisonnable de donnée que MySQL peu gérer?
Fuleran
SELECT COUNT(clef_primaire) FROM Table WHERE (conditions);

Essaye (en remplaçant évidament clef_primaire) avec ça mais je ne suis sure des chances d'amélioration.

As-tu bien défini une clef primaire sur ta table ?
Tes conditions font-elles appel à des champs indexés ?
Utilise-tu Mysql 4.1 ou 5 ?

Benoit

Mysql peux gérer des dizaines de millions d'enregistrement (leur record à 13 To de données si je me souviens bien)
skippy
j'utilise la version 4.1.7 sans possibilité d'en changer blush.gif
en tout cas merci fuleran ta proposition m'a deja fait gagné une demi seconde il me semble c'est dejà ca
adn
Y a-t-il bien des INDEX sur les champs de ta condition ?
Fuleran
pose des index (mêmes si il ne sont pas primaires ou unique) sur chacun des champs utilisés dans tes conditions.

Attention ça devrait te permettre d'optimiser en lecture, mais tu va perdre en écriture.
skippy
merci pour ces pistes je vais tester tout ca dès que mister mysql se sera remis...
Spidetra
CITATION(skippy @ lundi 15 mai 2006, 16h19)
j'utilise la version 4.1.7 sans possibilité d'en changer  blush.gif
en tout cas merci fuleran ta proposition m'a deja fait gagné une demi seconde il me  rolleyes.gif semble c'est dejà ca
*


Une demi-seconde de gain entre count(*) et count(primary_key), c'est vraiment psychologique rolleyes.gif
Ces deux instructions sont équivalentes.

Pourquoi ne pas poster :
- la structure de ta table
- les index sur ta table
- ta requête SQL complète.

Mettre des index c'est bien, mais à condition qu'ils soient utilisés dans ton SELECT. Un petit EXPLAIN te le diras.
skippy
merci pour vos conseils, la création d'index sur le champ de conditions m'a effectivement fait gagner plusieurs secondes biggrin.gif ... pour faire mieux il semblerait que la seule solution soit de changer le serveur...

IMSTP3.gif youpi c'est mon 100ème message sur le hub
Dan
CITATION(skippy @ mardi 16 mai 2006, 13h47)
IMSTP3.gif youpi c'est mon 100ème message sur le hub
*

Faut que je fasse gaffe à ne pas me faire doubler alors r_question6161.gif tongue.gif
Portekoi
Bonjour,

As tu un champ autoincremente dans ta table? Si oui, mets le en clé primaire et faire ceci :

SQL
SELECT COUNT(ID) FROM Table WHERE (conditions);



Portekoi

PS : Ca va, il a de la marge encore ^_^
Anonymus
Lors du 'select count', la base regarde d'abord ce qu'il y a à compter.
Normalement, il ne devrait pas y avoir de différences entre un select count(*) et select count(id) dans la mesure où la base sait qu'elle doit compter l'ensemble des lignes smile.gif

Pour info, avec un select count, sur une table de quelques millions de résultats, j'ai moins d'une seconde d'attente :
count(url_id)
3825277

(sur un serveur dédié normal....).

Peut être as tu un problème ailleurs.. Peux tu nous poster la structure de ta table ?

L'idée de mettre tous les champs en index n'est pas bonne. En effet, mysql est obligé de construire un index aussi grand que... les tables elles mêmes, ce qui réduit à néant l'effort consenti (avec 2 tables au lieu d'une wink.gif )

Par contre, il peut être judicieux de créer une table spéciale, plus légère, (avec 2/3 champs seulement), mais qui permettra de compter plus vite.

Une autre solution, préférée dans certains cas, est de compter au fur et à mesure, et de stocker les résultats ailleurs. Un exemple (qui n'a rien de formel ):
Sur ce forum, les posts des membres sont stockés dans une table 'posts'. On pourrait dépiler et compter le nombre de posts d'un membre ainsi, avec cette table.
La méthode choisie est d'incrémenter un compteur, dans la table 'membre', à chaque post posté.
Lorsque l'on affiche un membre, on dépile aussi une 'information de son profil', à savoir le nombre de posts qu'il a posté, au lieu d'aller chercher cette information dans une autre table, ce qui aurait eu pour effet de ralentir considérablement l'affichage de la page smile.gif

Il n'est pas génant de stocker des informations redondantes dans une base sql, à condition que ces redondances d'informations aient une certaine importance. Après, évidement, il faut faire attention à bien jongler avec les données, pour éviter les problèmes d'incohérence.
psylock
j'obterais pour la seconde solution d'Anonymus aussi
tu comptes au fur et à mesure et tu stocke cette information dans une table ou un fichier
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'information, la mise en page et les images, veuillez cliquer ici.