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

Langage SQL Discussion :

Faire une recherche de type "contient" sur deux colonnes


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut Faire une recherche de type "contient" sur deux colonnes
    Bonjour,

    J'ai une table qui se nomme "utilisateur" avec deux colonnes :
    - Nom,
    - Prénom.

    J'aimerai avoir tous les utilisateurs dont les noms ou prénoms contiennent plusieurs chaines différentes.

    Par exemple ma table :
    -------------------------
    | Nom | Prenom |
    -------------------------
    | Dupont | José |
    | Dupont | Albert |
    | Joss | Julien |
    | Toto | Tutu |
    -------------------------
    Je voudrais toutes les personnes dont le nom ou le prénom contiennent les chaines "Du" ou "Tu".

    Résultat :
    Dupont José
    Dupont Albert
    Toto Tutu

    J'ai deux solutions différentes :
    SELECT * FROM (select concat(Nom, Prenom) as NomPrenom from utilisateur) as req where NomPrenom like '%Du%' or NomPrenom like '%Tu%';
    ou
    SELECT * FROM utilisateur where concat(Nom, Prenom) like '%Du%' or concat(Nom, Prenom) like '%Tu%';
    J'aimerai savoir quelle est la meilleure ou s'il y a une solution encore plus performante ?

    Merci par avance.

  2. #2
    Membre expérimenté Avatar de Yanika_bzh
    Homme Profil pro
    Responsable Applicatif et R&D
    Inscrit en
    Février 2006
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Responsable Applicatif et R&D
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 1 144
    Points : 1 738
    Points
    1 738
    Par défaut
    dans tous les cas, l'utilisation d'un
    est contre performant
    Pour voir la difference entre vos 2 requetes, regardez le plan d'execution généré.

    Bon courage

  3. #3
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut
    Bonjour,

    Merci pour cette réponse.
    Après une rapide recherche sur mon ami google, on utilise la commande EXPLAIN pour faire un plan d'exécution de la requête.

    Quand j'exécute la requête :
    EXPLAIN
    SELECT * FROM (select concat(Nom, Prenom) as NomPrenom from utilisateur) as req where NomPrenom like '%Du%' or NomPrenom like '%Tu%';
    J'ai deux lignes en résultats :
    id -- select_type -- table -- type -- possible_keys -- key -- key_len -- ref -- rows -- Extra
    1 -- PRIMARY -- <derived2> -- ALL -- NULL -- NULL - NULL -- NULL -- 36 -- Using where
    2 -- DERIVED -- utilisateur -- ALL -- NULL -- NULL - NULL -- NULL -- 36 --

    Et quand j'exécute la requête :
    EXPLAIN
    SELECT * FROM utilisateur where concat(Nom, Prenom) like '%Du%' or concat(Nom, Prenom) like '%Tu%';
    J'ai une ligne en résultat :
    id -- select_type -- table -- type -- possible_keys -- key -- key_len -- ref -- rows -- Extra
    1 -- SIMPLE -- utilisateur -- ALL -- NULL -- NULL - NULL -- NULL -- 36 -- Using where


    Par contre je ne sais pas comment interpréter ces résultats ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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,

    MySql ?
    http://dev.mysql.com/doc/refman/5.0/...in-output.html

    La 1ere requête a une étape de plus car vous avez une sous-requête.

    Maintenant pour voir quelle solution est plus pertinente il faudrait que vous arriviez à sortir le coût réel de la requête.

    Ne connaissant pas plus que ça MySql je ne pourrai pas vous orienter la dessus.

  5. #5
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut
    Désolé je ne l'avais pas précisé, je travaille bien avec mysql.
    J'ai exécuté ces deux requêtes sur l'outil MySQL Query Browser.

    Merci pour la documentation, je l'ai déjà vu, il existe la même en français :
    http://dev.mysql.com/doc/refman/5.0/fr/explain.html

    Mon problème est que cela me donne peu d'indice qui me permettent de savoir laquelle est la plus performante/pertinente.
    En effet la première contient une sous requête donc est exécutée en deux fois donc potentiellement moins performante mais elle me permet d'exécuter qu'une seule fois la commande concat() qui peut être utilisée N fois dans la deuxième requête.

    Avec le résultat de EXPLAIN, je n'arrive toujours pas à me décidé car il y a peu de données.
    Je ne comprends pas non plus les résultats dans la colonne rows ("la colonne rows indique le nombre de ligne que MySQL estime devoir examiner pour exécuter la requête" ).
    Mon hypothèse serait que j'ai 2*36 instructions avec la sous-requête et 1*36 instructions avec la deuxième ?
    Donc la deuxième serait plus pertinente/performante même avec N fois concat() ?

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bah il existe une solution empirique aussi...
    Chargez votre table avec la volumétrie cible (voir plus grosse) et comparez.

    Si vous faites ca, testez aussi une solution sans le concat pour voir comment le sgbd réagi.

    D'ailleurs je me demande pourquoi vous faites un concat car le cas suivant ressortira de votre recherche par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    nom - prenom
    DUPONT ulysse

  7. #7
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut
    La taille de la table utilisateur n'est pas forcément très importante.

    Résultat de ma première requête :
    NomPrenom
    DupontJosé
    DupontAlbert
    TotoTutu

    Résultat de ma seconde requête :
    idUtilisateur -- Nom -- Prénom
    1 -- Dupont -- José
    2 -- Dupont -- Albert
    3 -- Toto -- Tutu

    Sinon d'un point de vue syntaxique, ces deux requêtes sont bonnes ?
    Il n'y aurait pas une autre manière de faire ?

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    oui, elles sont bonnes.
    L'autre manière de faire c'est virer le concat et faire plus de "or".


    Si votre volumétrie ne sera jamais importante vous n'aurez aucun problème avec ce genre de requête.

    Les problèmes viendront si votre table grossit vraiment, mais vu la demande il n'y aura pas de solution potable.

    A moins de faire de la consolidation dans une autre table si vos critères de recherche sont fixes ..

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour

    Citation Envoyé par Sango64 Voir le message
    mais elle me permet d'exécuter qu'une seule fois la commande concat() qui peut être utilisée N fois dans la deuxième requête.
    Utilisée N fois (deux fois en fait), mais exécutée qu'une fois quand même puisque concat est une fonction déterministe, et que les paramètres qui lui sont fournis sont les mêmes dans les deux cas

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/06/2011, 15h30
  2. Réponses: 2
    Dernier message: 08/10/2009, 14h42
  3. Réponses: 4
    Dernier message: 26/05/2006, 12h39

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