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. #21
    Membre éclairé
    Avatar de Kioob
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    550
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    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.
    C'est justement là que je ne suis pas d'accord : à aucun moment on a de GROUP BY avec la deuxième méthode... (au passage, on peut très bien faire un COUNT() avec mysql_query() d'ailleurs hein).

    • Cas 1 (simplifié) : mysql_query( "select id from article where type = 'toto'" ); $nb = mysql_num_rows();
    • Cas 2 (simplifié aussi) : mysql_query( "select count(*) from article where type = 'toto'" ); $nb = mysql_fetch_assoc();

      => Il n'y a aucun "group by" ici. De plus, le critère en question est même sûrement indexé, et donc MySQL n'ira même pas "compter les lignes" dans la table mais lira juste les infos dans l'index.




    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 ?
    Je voulais dire par là qu'il évitait justement de faire un "SELECT de récupération des données" suivi d'un "SELECT de comptage". Et je répète que c'est pour moi le seul cas où mysql_num_rows() est utile.



    j'utilise les guillemets car, techniquement, les tuples ne sont pas exactement retournés
    peux tu préciser ta pensée stp ?




    Quelle est la différence avec une requête mise en buffer puis parcourue ?
    Pour moi que l'appel soit fait via mysql_query() ou mysql_unbuffered_query() ne change pas grand chose coté serveur : le serveur lit les données sur le disque, et toutes les N lignes (suivant la taille de son tampon réseau) il envoit un paquet au client.

    Ce qui change c'est la façon dont le client gère la réception des paquets :
    • cas mysql_unbuffered_query() : le socket est lu à chaque appel de mysql_fetch_assoc()
    • cas mysql_query() : le socket est lu d'une traite par la fonction mysql_query(), et son contenu intégralement copié en mémoire. Chaque appel de mysql_fetch_assoc() va chercher les tuples en mémoire.


    La seule différence notable d'après moi est la consommation mémoire sur le client.
    Google is watching you !

  2. #22
    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
    Points : 29 985
    Points
    29 985
    Par défaut
    Flûte, nous allons avoir du mal à nous en sortir si nous continuons à mal nous comprendre :/


    Je pensais que tu n'appréciais pas le coup de faire deux mysql_unbuffered_query() à la suite, l'un servant à récupérer les données et l'autre à compter les tuples.
    Je reprends. Il y a trois solutions pour faire la même chose, dans une grande partie des cas :
    • 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
    • mysql_unbuffered_query() pour récupérer les données puis un autre mysql_unbuffered_query() pour compter les tuples

    Là, j'espère être clair.


    Citation Envoyé par Kirkis
    j'utilise les guillemets car, techniquement, les tuples ne sont pas exactement retournés
    C'était une imprécision de ma part. Ils ne sont pas retournés "en mémoire" : ils sont retournés dans un socket, selon ce que tu as dit. J'aurais envie de faire une analogie avec une gestion de pointeurs...


    Ok, donc pour la différence entre les deux fonctions _query(), il s'agit de choisir entre lire le socket et lire la mémoire (qui est une copie du socket en ce cas). Je n'avais pas vu les choses de ce point de vue mais cela se tient.


    Ma journée se termine, je ne sais pas si je pourrai revenir avant lundi (et c'est bien triste).
    Merci bien pour la discussion, en tout cas.

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    mysql_unbuffered_query() avec la même requête que ci-dessus incluant une colonne COUNT() et, par conséquent, un GROUP BY
    rah... tu en veux à ce GROUP BY ! Je persiste : aucunement besoin, de cela.

    Sinon, on est bien d'accord, il y a 3 méthodes classiques (on pourrait en fait ajouter le "select" classique, avec un compteur géré via PHP... pas tres sexy, mais dans certains cas, pourquoi pas).


    Ok, donc pour la différence entre les deux fonctions _query(), il s'agit de choisir entre lire le socket et lire la mémoire (qui est une copie du socket en ce cas). Je n'avais pas vu les choses de ce point de vue mais cela se tient.
    Yep, et dans le cas d'un grand nombre de lignes retournées par la requète, la consommation mémoire peut avoir des effets desastreux sur les performances globales du serveur.


    Merci bien pour la discussion, en tout cas.
    de même
    Google is watching you !

  4. #24
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Salut,

    Si dans mon client mysql je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    mysql> select * from classement;
    +---------+-----+
    | nom     | pts |
    +---------+-----+
    | pierre  |  10 |
    | paul    |  10 |
    | jacques |  10 |
    | jean    |  10 |
    | marie   |   0 |
    +---------+-----+
    5 rows in set (0.01 sec)
     
    mysql>
    Le 5 rows en 0.01 secondes, c'est qui qui le fourni ? le client mysql ou le serveur ? pareil pour la durée 0.01 sec ?

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    Mr N : je n'en suis pas sûr à 100%, mais pour moi c'est le client.

    Mais si tu fais un UPDATE, le affected_rows c'est le serveur qui le renvoit.
    Google is watching you !

  6. #26
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Kioob, je pense que tu n'es pas loin des 100% :
    Sachant que mysql_query appelle mysql_read_query_result =>
    Citation Envoyé par libmysql/libmysql.c
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    int STDCALL mysql_read_query_result(MYSQL *mysql)
    {
      ...
      ...
      if ((field_count= net_field_length(&pos)) == 0)
      {
        mysql->affected_rows= net_field_length_ll(&pos);
        ...
        ...
      }
      ...
      ...
      if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
        DBUG_RETURN(-1);
      ...
      ...
    }
    ...
    ...
    static MYSQL_DATA *read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
                                 uint fields)
    {
      ...
      ...
      MYSQL_DATA *result;
      ...
      ...
      if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
                                           MYF(MY_WME | MY_ZEROFILL))))
      ...
      ...
      result->rows=0;
      ...
      ...
     
      while (*(cp=net->read_pos) != 254 || pkt_len != 1)
      {
        result->rows++;
        ...
        ...
      }
      ...
      ...
    }
    Ce que je lis dans cet extrait de code :
    - affected_rows est donné par le serveur
    - num_rows est construit "à la volée" lors de la récupération des lignes;

    CQFD

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    ah, bah merci pour ces précisions
    Google is watching you !

  8. #28
    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
    Points : 29 985
    Points
    29 985
    Par défaut
    @Kioob

    Essaie une requête de ce type sans mettre de GROUP BY, pour voir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT `username`, COUNT(*) AS `nb_of_users`
    FROM `phpbb_users`;
    Si ça passe, tu m'appelles et on en rediscute ? :p

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    Kirkis : c'est bien ce que je disais, on ne parlait pas de la meme chose...

    moi je te parle de ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT COUNT(*) AS `nb_of_users`
    FROM `phpbb_users`;
    C'est à dire un comptage. Parce que 90% des personnes font des "SELECT *" suivi d'un mysql_num_rows() uniquement pour faire un comptage...
    Google is watching you !

  10. #30
    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
    Points : 29 985
    Points
    29 985
    Par défaut
    C'est que j'étais dans l'idée de mettre le SELECT et le COUNT dans la même requête (cf. cas #2 dans mes exemples ci-dessus).

    Je ne connaissais pas cette statistique, c'est peut-être pour cela que je m'obstinais à imposer mon COUNT et que tu ne me comprenais pas...

    Bon, tout est réglé ? Nous n'avons pas dit trop de bêtises ?

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 550
    Points : 764
    Points
    764
    Par défaut
    arf

    disons que cette "statistique" sort tout droit de se forum


    pour les bétises... bah... non... je crois pas, mis à part qu'on s'est pas mal répétés
    Google is watching you !

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