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

Requêtes MySQL Discussion :

Perf pour chercher existence : count ou select ?


Sujet :

Requêtes MySQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 68
    Points : 40
    Points
    40
    Par défaut Perf pour chercher existence : count ou select ?
    Bonjour à tous,

    Je veux juste savoir si un enregistrement existe en fonction d'un critère. Quelle est la requête la plus performante ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT COUNT(*) FROM matable WHERE ...
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id FROM matable WHERE ... LIMIT 1
    ou autre ?

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Intéressante interrogation !

    Ta seconde requête laisse supposer qu'il peut y avoir plusieurs id satisfaisant au critère.

    Je pense qu'avec cette seconde requête, le SGBD va d'abord extraire toutes les lignes satisfaisant au critère puis limiter le jeu de résultat à la première ligne.

    La première requête va compter le nombre de lignes satisfaisant le critère.
    Il est possible que l'opération de comptage ajoute du temps par rapport à la première requête.

    Encore que si le critère est basé sur un index, peut-être que le comptage se fait directement sur l'index sans extraire les informations des lignes ?

    Il faudrait un spécialiste de la mécanique de MySQL pour répondre.

    Bien sûr, la différence ne se fera sentir qu'avec un grand nombre de lignes dans la table.

    L'idéal serait peut-être une requête de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT EXISTS (
      SELECT *
      FROM matable
      WHERE critere
    )
    Elle devrait s'arrêter à la première ligne trouvée satisfaisant le critère.
    Mais je ne suis pas sûr qu'elle soit syntaxiquement valide.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Je pense qu'avec cette seconde requête, le SGBD va d'abord extraire toutes les lignes satisfaisant au critère puis limiter le jeu de résultat à la première ligne.
    C'est horrible s'il fait ca.

    Sans ORDER BY il devrait sortir dès qu'il satisfait sa condition au vu de son scan de table.


    En fait c'est un peu le même problème qu'ici : http://www.developpez.net/forums/d11...ation-requete/

    Mais vu qu'on a pas eu les EXPLAIN c'est difficile de se pronnoncer (car 2sec pour scanner à l'envers un index c'est beaucoup je trouve...)

  4. #4
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Intéressante interrogation !
    Bien sûr, la différence ne se fera sentir qu'avec un grand nombre de lignes dans la table.

    L'idéal serait peut-être une requête de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT EXISTS (
      SELECT *
      FROM matable
      WHERE critere
    )
    Je viens de tester cette syntaxe sous SQLite (je n'ai pas de MySQL sous la main.)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CASE WHEN EXISTS(SELECT DEBIT FROM JOURNAUX WHERE DEBIT=167.35) THEN "TROUVE" ELSE "PAS TROUVE" END
    qui fonctionne.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  5. #5
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Comment MySQL optimise LIMIT
    Moi je vote pour la requête avec LIMIT.

    Ou sinon comme ça avec DUAL:
    You are permitted to specify DUAL as a dummy table name in situations where no tables are referenced:

    mysql> SELECT 1 + 1 FROM DUAL;
    -> 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT 1 from dual
     where EXISTS (SELECT *
                     FROM matable
                    WHERE critere)

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Bonjour,

    J'ai fait quelques tests sur des tables INNODB et MYISAM avec des critères de recherche différents.
    Dans tous les cas que j'ai testé, la requête avec LIMIT est soit beaucoup plus rapide soit identique au SELECT count(*).

    Je n'ai pas vu d’amélioration en utilisant le "SELECT EXISTS"

Discussions similaires

  1. Besoin d'explication pour WHERE EXISTS(SELECT NULL..
    Par Mr Pink Eyes dans le forum Langage SQL
    Réponses: 3
    Dernier message: 21/06/2007, 11h22
  2. Réponses: 2
    Dernier message: 28/10/2005, 12h52
  3. Réponses: 5
    Dernier message: 29/08/2005, 14h51
  4. Aide pour une requete ... "COUNT(*)"
    Par mechantebestiole dans le forum Langage SQL
    Réponses: 13
    Dernier message: 25/05/2004, 16h27
  5. [LG]pour l'existence des fichiers en pascal
    Par mister_dsg dans le forum Langage
    Réponses: 8
    Dernier message: 04/12/2003, 22h14

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