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

SQL Procédural MySQL Discussion :

Question mysql_num_rows [FAQ]


Sujet :

SQL Procédural MySQL

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2005
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 513
    Par défaut Question mysql_num_rows
    Bonjour a tous,
    en fait j'aimerais juste savoir, pour connaitre le nombre de resultat que l'on a à une requête, on fait mysql_num_rows + 1?
    car j'ai l'impression que si j'ai une seul ligne de resultat, bah mysql_num_rows me renvoie 0.
    Vous confirmer?
    Merci par avance
    Bob

  2. #2
    Membre Expert
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Par défaut
    non je ne suis pas d'accord

    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
    <?php
     
    $link = mysql_connect('localhost', 'root', '');
    if (!$link) {
       die('Impossible de se connecter : ' . mysql_error());
    }
     
    // Rendre la base de données foo, la base courante
    $db_selected = mysql_select_db('test', $link);
    if (!$db_selected) {
       die ('Impossible de sélectionner la base de données : ' . mysql_error());
    }
     
    $sql = "SELECT * FROM celko1in10 LIMIT 0,1";
    $query=mysql_query($sql);
    echo mysql_num_rows($query); // affiche 1
    ?>

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2005
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 513
    Par défaut
    en fait c t pour faire un controle, mais c'est pas grave, je me suis démerder autrement.
    pourtant c'est bizar par que je tester si le nombre de ligne était inférieur ou égal à 0 pour savoir si ma requete avec un resultat, mais elle avait beau avoir un resultat, ca me mettai l'erreur.
    mais bon j'ai changé ma façon de faire.
    désoler pour le dérangement et merci pour la réponse rapide!

  4. #4
    Membre Expert
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Par défaut
    Ouè, vu que je ne sais pas de quel code tu parles je ne sais que te répondre

  5. #5
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 668
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 668
    Par défaut
    Citation Envoyé par LordBob
    pourtant c'est bizar par que je tester si le nombre de ligne était inférieur ou égal à 0 pour savoir si ma requete avec un resultat, mais elle avait beau avoir un resultat, ca me mettai l'erreur.
    c'était peut-être la requête qui avait un problème
    pour gagner du temps je te conseille de lancer tes requêtes comme indiqué dans la FAQ comme ça en cas d'erreur tu vois tout de suite ce qu'il se passe :
    http://php.developpez.com/faq/?page=...ysql_ressource

  6. #6
    Membre expérimenté

    Inscrit en
    Mai 2004
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 162
    Par défaut
    Et aussi de voir du côté de la fonction mysql_affected_rows(), moins gourmande en ressources semble t'il que mysql_num_rows().

  7. #7
    Membre Expert
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Par défaut
    C'est pas le même usage :s non ?

  8. #8
    Membre expérimenté

    Inscrit en
    Mai 2004
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 162
    Par défaut
    mysql_num_rows n'est valable que pour les SELECT... tandis que mysql_affected_rows fonctionne pour les requêtes les plus fréquentes (SELECT, INSERT, UPDATE etc)

  9. #9
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2005
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 513
    Par défaut
    mathieu << je suis sur que cela ne vient pas de ma requête pour preuve, elle fonctionner tres bien avant que je ne me serve de mysql_num_rows().

    Moloc'h << merci pour l'info. je tacherai d'utiliser celle, car si elle marche pour n'importe quel requête, ca peut être tres interressant !

  10. #10
    Membre expérimenté

    Inscrit en
    Mai 2004
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 162
    Par défaut
    On peut voir à quoi ressemble la requête ? Un peu de code ?

  11. #11
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2005
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 513
    Par défaut
    bien sur ma de probleme, voici la requete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT IdUtilisateur FROM UTILISATEUR WHERE LoginUtilisateur='xxxx' AND PasswordUtilisateur='yyyy';
    ensuite voila le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $result = mysql_query($requete);
    return(mysql_num_rows($result));
    et puis loins je fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(fonction(param) <= 0)
      // erreur
    et voila ce qui bug!
    or si j'enlévé le if, ça marche très bien!

  12. #12
    Membre Expert
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Par défaut
    C'est ptet que les logins n'était pas bon pendant tes test


  13. #13
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2005
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 513
    Par défaut
    nan, aucune chance.

  14. #14
    Membre émérite
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Par défaut
    Citation Envoyé par Moloc'h
    mysql_num_rows n'est valable que pour les SELECT... tandis que mysql_affected_rows fonctionne pour les requêtes les plus fréquentes (SELECT, INSERT, UPDATE etc)
    euh... le affected rows n'est en théorie pas affecté par un SELECT... d'ailleurs d'après la doc ce n'est pas le cas.

    Et de manière générale : autant mysql_affected_rows() est souvant utile, autant mysql_num_rows() est rarement approprié.

  15. #15
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Salut

    mysql_affected_rows() retourne le nombre de lignes affectées (donc uniquement en écriture, le DELETE étant considéré comme telle) tandis que mysql_num_rows() retourne le nombre de lignes sélectionnées (donc uniquement en lecture).

    @LordBob : mysql_num_rows() ne rendra jamais un résultat inférieur à zéro (cela n'aurait pas de sens), tu peux donc faire le test sur == 0 plutôt que sur <= 0

    Kioob : de mon côté, j'utilise bien plus souvent mysql_num_rows() que mysql_affected_rows().

  16. #16
    Membre émérite
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Par défaut
    Kioob : de mon côté, j'utilise bien plus souvent mysql_num_rows() que mysql_affected_rows().
    Et bien pour moi mysql_num_rows() ne sert pas à grand chose : quand tu veux connaitre le nombre d'enregistrement, une requete count() est bien plus performante, notament parce qu'elle évite le rappatriement des données. Cette fonction n'est donc utile que lorsque l'on veut de toutes façons rappatrier les données ET que l'on veut également les compter (ça évite que MySQL recherche 2 fois les données).
    De plus, pour pouvoir l'utiliser il faut utiliser mysql_query() qui bufferise le résultat... hors j'ai tendance à utiliser mysql_unbuffered_query(), plus rapide et moins gourmande en mémoire.

    Pour mysql_affected_rows(), son utilisation n'est pas fréquente, mais est toujours appropriée.

  17. #17
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Nous entrons dans le vif d'un sujet qui m'intéresse mais qui n'a plus grand chose à voir avec celui du départ :/

    Je me disais, peut-être naïvement, que mysql_num_rows() retourne une valeur qu'il a calculé de toute manière. Ainsi, un appel à mysql_num_rows() serait plus rapide (ou réellement plus simple à gérer) qu'une nouvelle requête SELECT COUNT(). À moins que tu parles d'inclure le COUNT() dans la requête courante, ce qui implique souvent l'implication de GROUP BY et qui, par conséquent, a un gros effet sur les performances (je compare avec un appel à mysql_num_rows())...

    Concernant mysql_unbuffered_query(), j'avoue avoir du mal à en saisir l'efficacité... Étant donné que je parcours de toute manière mes résultats pour les afficher, autant que MySQL les mette en cache : cela me permettra d'utiliser mysql_num_rows() sans avoir d'implication réelle sur les performances (puisque les résultats sont en cache, pas besoin d'aller les chercher physiquement dans la BDD, ce qui serait nécessaire avec mysql_unbuffered_query()).

    J'ai l'impression que la différence entre nos points de vue se situe dans le fonctionnement de mysql_num_rows() : à quel moment MySQL et/ou PHP calculent-ils ce résultat ?
    Je suis d'avis que c'est plus ou moins fait pendant l'exécution de la requête, tandis que tu sembles d'avis que c'est fait a posteriori (lors de l'appel à la fonction).

  18. #18
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2005
    Messages : 774
    Par défaut
    J'ai l'impression que la différence entre nos points de vue se situe dans le fonctionnement de mysql_num_rows() : à quel moment MySQL et/ou PHP calculent-ils ce résultat ?
    Je suis d'avis que c'est plus ou moins fait pendant l'exécution de la requête, tandis que tu sembles d'avis que c'est fait a posteriori (lors de l'appel à la fonction).
    je suis tout a fait d'accord avec toi Kirkis. mysql_num_rows est bcp plus efficient q de faire un select count. et de toute façon c'est bcp plus pratique. de toute façon les avis resteront partagés.

  19. #19
    Membre émérite
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Par défaut
    Effectivement on s'écarte un poil du sujet... mais si c'est pour s'expliquer, ça va encore

    Je commence par éclaircir un point :
    dans tous les cas mysql_num_rows() retournera le nombre total de lignes, donc un simple COUNT() donne le même résultat, aucunement besoin de faire des GROUP BY fort consommateurs.


    Donc, pour mieux comprendre les différences, voici quelques précisions :
    - COUNT() est une fonction SQL, exécutée par le serveur MySQL (donc sur la machine faisant tourner MySQL).
    - mysql_num_rows() est une fonction PHP, exécutée par PHP (donc généralement sur le serveur faisant tourner Apache).

    La fonction mysql_num_rows() en elle même est extrèmement rapide et non consommatrice : elle ne fait que retourner la valeur d'un compteur stocké par PHP**.
    Le problème, c'est que c'est la fonction mysql_query() qui rempli ce compteur :
    1) elle exécute la requete SELECT auprès du serveur MySQL comme demandé
    2) elle télécharge et conserve en mémoire toutes les lignes de résultats (qu'il y en ait seulement 5 ou 3 millions, le résultat est le même)
    3) au fur et à mesure de ce "téléchargement", elle met à jour le compteur "num_rows"

    => Avantage : le résultat une fois stocké en local, on peut en faire ce qu'on veut : "se déplacer" dedans, revenir en arrière, afficher plusieurs fois les mêmes lignes, etc etc.
    => Inconvénients :
    - le serveur va faire des accès disque pour lire les enregistrements demandés
    - le client va télécharger des données éventuellement conséquentes (= consommation de la bande passante)
    - le client va consommer de la mémoire pour stocker tous ces enregistrements


    Tandis qu'avec une requete COUNT(), pour peu que des INDEX correspondent aux critères de recherche, le serveur ne fera même pas d'accès disque, il va simplement retourner une (et une seule) valeur : le nombre d'enregistrement.
    Avantages :
    - pas d'accès disque pour le serveur
    - quelques octets à transfèrer uniquement
    - une seule ligne de résultat coté client à stocker

    Mais il y un inconvénient : si le client fait une requete COUNT(), il n'obtient évidement que le nombre d'enregistrements... mais certainement pas les enregistrements en question. Et c'est là qu'intervient mysql_num_rows() : dans le cas où le client veut à la fois le nombre d'enregistrements et la liste des enregistrements, alors cette fonction est bien souvent adaptée. Car par contre il serait ridicule d'exécuter un COUNT() suivi du SELECT permettant de récupèrer les enregistrements...



    Pour mysql_unbuffered_query(), c'est une autre histoire : avec mysql_query() c'est le client qui met le résultat de coté, au cas où le script voudrait y accèder plusieurs fois d'affilée (au sein d'une même "instance" du script hein, ce n'est pas un cache local non plus). Or, dans le cas d'un site web c'est rarement le cas. Comme tu le dis, dans 80% des cas on va simplement afficher le résultat... donc inutile de consommer de la mémoire pour stocker ces données, autant les afficher directement.




    ** je précise que je n'ai pas regardé le code source de PHP en détail, donc quand je dis que c'est PHP qui compte, stocke en mémoire, etc, il se peut qu'il s'agisse de fonctions offertes par l'API MySQL utilisée dans PHP. Néanmoins le résultat est le même, ce travail est effectué sur le client et non sur le serveur.

  20. #20
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Juste pour que tout le monde suive bien : dans la démonstration de Kioob, le "serveur" est MySQL et le "client" est PHP.
    Je reformule : nous ne parlons pas de PHP côté serveur (comme à l'accoutumée lorsqu'il s'agit de Web) mais de PHP en tant que client qui pose des questions à MySQL.


    Lorsque j'évoquais le GROUP BY, c'était pour comparer les stratégies suivantes dans le cas où l'on souhaite savoir combien il y a de tuples :
    • mysql_query() puis mysql_num_rows()
    • mysql_unbuffered_query() avec la même requête que ci-dessus incluant une colonne COUNT() et, par conséquent, un GROUP BY
    Nous sommes visiblement d'accord sur ce point : il est préférable d'éviter ce type de COUNT()
    Il y a une autre solution que tu as évoquée comme "ridicule" et j'adhère à ton avis sur ce point.
    On a side note: je considère la seconde des méthodes ci-dessus comme étant tout aussi ridicule.


    Merci pour la précision sur le fonctionnement de mysql_num_rows(), il correspond à ce que je soupçonnais.
    J'avais supposé que tu lui attribuais un fonctionnement différent à cause de cette remarque :
    Citation Envoyé par Kioob
    ça évite que MySQL recherche 2 fois les données
    Je me suis visiblement trompé. Que voulais-tu dire ?


    Maintenant, au sujet des différences entre mysql_query() et sa version non bufferisée...
    La doc recommande de parcourir tous les tuples "retournés" par mysql_unbuffered_query() (j'utilise les guillemets car, techniquement, les tuples ne sont pas exactement retournés).
    Quelle est la différence avec une requête mise en buffer puis parcourue ?
    J'y vais de mes suppositions :
    • cas mysql_unbuffered_query() :
      [list:e7315c3760]
    • à chaque appel à mysql_fetch_assoc(), il va falloir aller chercher le résultat sur le disque
    • un accès distinct pour aller chercher chaque tuple
    [*]cas mysql_query() :
    • à chaque appel à mysql_fetch_assoc(), pas besoin d'aller jusqu'au disque puisque tout est en cache.
    • un seul accès pour aller chercher tous les tuples de manière ensembliste : ça s'optimise comme ça veut mais ça s'optimise forcément, non ?
    [/list:u:e7315c3760]

Discussions similaires

  1. Réponses: 2
    Dernier message: 11/08/2002, 21h27
  2. Divers questions
    Par Freakazoid dans le forum DirectX
    Réponses: 2
    Dernier message: 06/08/2002, 21h57
  3. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11
  4. Question de faisabilité
    Par lisarasu dans le forum CORBA
    Réponses: 3
    Dernier message: 14/05/2002, 11h26
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 29/04/2002, 23h18

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