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

PHP & Base de données Discussion :

Nombre d'éléments récupérés avec un SELECT


Sujet :

PHP & Base de données

  1. #1
    Membre émérite
    Avatar de Seb33300
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 563
    Points : 2 390
    Points
    2 390
    Par défaut Nombre d'éléments récupérés avec un SELECT
    Bonjour,

    Je viens de me mettre à PDO et je me demandais si il existait un équivalent à mysql_num_rows() car je n'en vois pas dans la doc PHP.

    Bien sur je pourrais utiliser une requête avec COUNT() mais ça oblige à faire une 2ème requête...

    Merci
    Zend Certified PHP Engineer

    « Crois-tu comprendre le monde juste en matant le 20H Ou connaître l'histoire en ayant lu que l'angle des vainqueurs ? » Keny Arkana

  2. #2
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 098
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 098
    Points : 8 207
    Points
    8 207
    Billets dans le blog
    17
    Par défaut
    La doc préconise une 2e requête SELECT COUNT( ) http://fr.php.net/manual/en/pdostatement.rowcount.php
    Autrement tu peux faire un count($statement->fetchAll( ))
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  3. #3
    Rédacteur
    Avatar de jsd03
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Août 2008
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Août 2008
    Messages : 1 221
    Points : 6 506
    Points
    6 506
    Par défaut
    Au vu de la réponse de Sèb., je dirais que le plus rapide serait de faire une seconde requête avec un SELECT count()... parce que faire count($statement->fetchAll( )) puis un $statement->fetchAll( ) par la suite revient à faire deux fois la requête, qui si elle renvoit beaucoup de ligne peut ralentir considérablement le traitement.
    Google est ton ami mais ton voisin aussi

    Modérateur BI - Responsable Talend
    Mes tutoriels - FAQ Talend - FAQ SQL*Plus

    Avant toute chose : lire le mode d'emploi du forum et ses règles.
    Suivez @Developpez sur twitter !

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    parce que faire count($statement->fetchAll( )) puis un $statement->fetchAll( )
    heu il faut evidemment recuperer le resultat du fetchAll()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $result = $sth->fetchAll();
    $nbre = count($result);
    foreach ($result as $row) {
    }
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre émérite
    Avatar de Seb33300
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Thaïlande

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 563
    Points : 2 390
    Points
    2 390
    Par défaut
    Je pense que la méthode du fetchAll() est la mieux.

    Parce que 2 requêtes, sur un serveur qui est déjà assez chargé je pense que ce n'est pas ce qu'il y a de mieux.

    C'est vraiment dommage que le rowCount ne renvoi pas la valeur à tous les coups.
    D'ailleurs il est écrit que pour certaines BDD, le nombre est renvoyé. Qu'en est il pour MySQL, la valeur est elle renvoyé ? Y a t il quelque chose à paramétrer pour que cela fonctionne ?
    Zend Certified PHP Engineer

    « Crois-tu comprendre le monde juste en matant le 20H Ou connaître l'histoire en ayant lu que l'angle des vainqueurs ? » Keny Arkana

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Tout dépend de la requête.

    Si vous faites de la pagination sur un très gros résultat, par exemple résultats 1-10, 11-20, ... 51-60... sur un total de 500 000 lignes, je vois mal faire un SELECT sur les 500000 lignes puis un count du fetchAll alors que l'on en affiche que 10 ! Dans ce cas il FAUT faire une deuxième requête SELECT COUNT(*), sinon le serveur de base de données et le réseau vont souffrir !

    Par contre, si le résultat comporte peu de lignes toutes affichées à l'écran, là effectivement il vaut mieux faire un count sur le tableau renvoyé par fetchAll.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 43
    Points : 58
    Points
    58
    Par défaut PDO et count
    il existe tout simplement la méthode rowcount() applicable à l'objet ResultSet.
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
    	header("Content-Type: text/html; charset=UTF-8");
    	$cn = new PDO('mysql:host=localhost;dbname=cours','root','');
    	$rs = $cn->query('SELECT * FROM villes');
    	echo $rs->rowcount();
    	$cn = null;
    ?>

  8. #8
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 098
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 098
    Points : 8 207
    Points
    8 207
    Billets dans le blog
    17
    Par défaut
    Citation Envoyé par pascalbuguet Voir le message
    il existe tout simplement la méthode rowcount() applicable à l'objet ResultSet.
    Oui mais la doc de PDOStatement::rowCount( ) précise :

    Si la dernière requête SQL exécutée par l'objet PDOStatement associé est une requête de type SELECT, quelques bases de données retourneront le nombre de lignes retournées par cette requête. Néanmoins, ce comportement n'est pas garanti pour toutes les bases de données et ne devrait pas être exécuté pour des applications portables.
    ... ce qui casse qque peu son intérêt.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  9. #9
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    rowCount est censé donner le nomber de lignes affectées, pas le nombre de lignes retournées par un SELECT.
    En mysql, sous toute reserve, cela fonctionne aussi pour un SELECT, mais d'autres moteurs pourraient ne pas fonctionner ainsi.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2006
    Messages : 43
    Points : 58
    Points
    58
    Par défaut
    bonjour,
    vous avez entièrement raison.
    J'ai relu mes notes sans aller vers la doc "officielle".
    Par curiosité je suis allé faire quelques tests malheureusement très concluants.

    Voici quelques remontées.

    1 - MySQL natif : OK
    2 - MySQL via ODBC : OK
    3 - SYBASE via OBDC : OK

    4 - MS-Access via ODBC : KO
    5 - SQL Server via ODBC et pilote natif : KO

    6 - SQL Server via mssql : triple KO (de toutes les façons MS recommande le passage via ODBC qui est KO)

    7 - Oracle via ODBC : @+
    8 - Oracle via natif : @+
    Pour Oracle je ne l'ai pas sous la main aujourd'hui !

    Je crois que le problème n'est pas tellement du SGBDR mais du pilote et de son paramétrage.
    Quand nous aurons ??? des méthodes permettant de paramétrer les curseurs ce sera plus sûr.
    Pour l'instant vous avez tous raison, un bon vieux SELECT COUNT(*) FROM ... vaut mieux que 2 tu l'auras :-)

    Mis à part ça je reste un fan (modéré) de PDO parce ses performances sont vraiment très bonnes par rapport à des pear.DB ou pear.mbd2, ...

    Bonne journée

  11. #11
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Personnellement je fais comme indiqué : si j'ai besoin de connaitre le nombre d'enregistrement, je fais un fetchAll.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Personnellement je fais comme indiqué : si j'ai besoin de connaitre le nombre d'enregistrement, je fais un fetchAll.
    Ce qui est adapté lorsque l'on va de toute façon tout afficher, mais lorsque l'on a une recherche qui retourne potentiellement 500000 enregistrements, que l'on veut connaitre ce chiffre de 500000 mais n'en afficher que 10 ou 20 comme google, on ne va pas récupérer les 500000 lignes pour pouvoir les compter () : on fait un COUNT() pour obtenir 500000 et un SELECT qui ne récupère que les 10 ou 20 lignes, ce qui comme je le disais plus haut soulage le SGBD et le réseau.

  13. #13
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    La problème n'a pas changé depuis les extensions classiques alors.
    Je ne pense pas qu'auparavant, tu faisais un SELECT de tous les enregistrements pour n'en afficher que 20.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Points : 220
    Points
    220
    Par défaut
    Citation Envoyé par sabotage Voir le message
    La problème n'a pas changé depuis les extensions classiques alors.
    Si tu veux dire que PDO n'apporte rien dans ce domaine par rapport aux anciennes extensions, c'est tout à fait ça.

    Ce problème de comptage de résultat n'est pas anodin et dépend essentiellement du SGBD, pas de l'API.

    Comme je le disais, la solution de tout récupérer (toutes les lignes et colonnes affichées) puis de les compter n'est pas valable dans le cas général, d'où la nécessité, pour schématiser, du SELECT COUNT avant le SELECT *...

    Je maintiens ceci, mais je tiens également à souligner que les perfs du SELECT COUNT sont très variables selon les SGBD et selon les indexes mis en place.

    MySQL est optimisé pour le SELECT COUNT (un des rares avantages de MySQL sur les autres SGBD, soit dit en passant), ce n'est donc pas très couteux.

    Pour PostgreSQL ce n'est pas terrible et il est prévu une optimisation du COUNT mais je ne sais pas pour quand.

    Oracle a le même pb que PostgreSQL actuellement : le COUNT est couteux et revient (presque) exactement à faire le SELECT * mais côté serveur uniquement (sans l'envoi des données vers le client effectué avec SELECT *, l'envoi de beaucoup de données étant également lourd pour le SGBD). Pourquoi le "presque" ? Parce qu'un COUNT(id) et des critères de recherche bien indexés peuvent n'entrainer que des balayages d'indexes, pas des enregistrements en eux-mêmes, ce qui est en général beaucoup plus rapide.

Discussions similaires

  1. [XL-2010] Nombre d'éléments distincts avec plusieurs conditions
    Par Altasis dans le forum Excel
    Réponses: 10
    Dernier message: 09/02/2013, 14h45
  2. création boucle avec x nombre d'éléments
    Par masky dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 05/09/2007, 09h55
  3. [AJAX] Compter le nombre d'élément d'un page.select ?
    Par titoumimi dans le forum Ruby on Rails
    Réponses: 21
    Dernier message: 09/05/2007, 12h48
  4. Nombre d'éléments d'un <select> à l'ouverture
    Par philippe123 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 25/07/2006, 16h59
  5. Compter nombre d'éléments avec valeur X dans un formulaire
    Par p0Kep0K dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 24/11/2005, 15h49

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