Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 02/12/2011, 11h39   #1
Invité régulier
 
Inscription : juillet 2011
Messages : 31
Détails du profil
Informations forums :
Inscription : juillet 2011
Messages : 31
Points : 6
Points : 6
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 :
SELECT COUNT(*) FROM matable WHERE ...
ou
Code :
SELECT id FROM matable WHERE ... LIMIT 1
ou autre ?
eprevot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 12h21   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 11 029
Points : 18 327
Points : 18 327
Envoyer un message via MSN à CinePhil
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 :
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 13h33   #3
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 648
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 648
Points : 2 646
Points : 2 646
Bonjour,

Citation:
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...)
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 13h47   #4
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

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

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
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 :
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 :
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)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/12/2011, 14h05   #5
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Comment MySQL optimise LIMIT
Moi je vote pour la requête avec LIMIT.

Ou sinon comme ça avec DUAL:
Citation:
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 :
1
2
3
4
SELECT 1 FROM dual
 WHERE EXISTS (SELECT *
                 FROM matable
                WHERE critere)
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/12/2011, 18h21   #6
Membre du Club
 
Homme Frédéric
Inscription : juin 2011
Messages : 52
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Localisation : France

Informations forums :
Inscription : juin 2011
Messages : 52
Points : 52
Points : 52
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"
Fred_34 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h08.


 
 
 
 
Partenaires

Hébergement Web