skippy Posté 15 Mai 2006 Posté 15 Mai 2006 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... SELECT * FROM Table WHERE (conditions); y a t il un moyen plus rapide que mysql_num_rows($query); 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 Posté 15 Mai 2006 Posté 15 Mai 2006 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 Posté 15 Mai 2006 Auteur Posté 15 Mai 2006 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 Posté 15 Mai 2006 Posté 15 Mai 2006 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 Posté 15 Mai 2006 Auteur Posté 15 Mai 2006 j'utilise la version 4.1.7 sans possibilité d'en changer en tout cas merci fuleran ta proposition m'a deja fait gagné une demi seconde il me semble c'est dejà ca
Fuleran Posté 15 Mai 2006 Posté 15 Mai 2006 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 Posté 15 Mai 2006 Auteur Posté 15 Mai 2006 merci pour ces pistes je vais tester tout ca dès que mister mysql se sera remis...
Spidetra Posté 15 Mai 2006 Posté 15 Mai 2006 j'utilise la version 4.1.7 sans possibilité d'en changer en tout cas merci fuleran ta proposition m'a deja fait gagné une demi seconde il me semble c'est dejà ca <{POST_SNAPBACK}> Une demi-seconde de gain entre count(*) et count(primary_key), c'est vraiment psychologique 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 Posté 16 Mai 2006 Auteur Posté 16 Mai 2006 (modifié) merci pour vos conseils, la création d'index sur le champ de conditions m'a effectivement fait gagner plusieurs secondes ... pour faire mieux il semblerait que la seule solution soit de changer le serveur... youpi c'est mon 100ème message sur le hub Modifié 16 Mai 2006 par skippy
Dan Posté 16 Mai 2006 Posté 16 Mai 2006 youpi c'est mon 100ème message sur le hub Faut que je fasse gaffe à ne pas me faire doubler alors
Portekoi Posté 16 Mai 2006 Posté 16 Mai 2006 Bonjour, As tu un champ autoincremente dans ta table? Si oui, mets le en clé primaire et faire ceci : SELECT COUNT(ID) FROM Table WHERE (conditions); Portekoi PS : Ca va, il a de la marge encore
Anonymus Posté 19 Mai 2006 Posté 19 Mai 2006 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 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 ) 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 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 Posté 20 Mai 2006 Posté 20 Mai 2006 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
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant