Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
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 26/07/2011, 14h49   #1
Membre à l'essai
 
Inscription : octobre 2009
Messages : 63
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 63
Points : 22
Points : 22
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 :
Citation:
-------------------------
| 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 :
Citation:
SELECT * FROM (select concat(Nom, Prenom) as NomPrenom from utilisateur) as req where NomPrenom like '%Du%' or NomPrenom like '%Tu%';
ou
Citation:
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.
Sango64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/07/2011, 15h01   #2
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
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
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 09h05   #3
Membre à l'essai
 
Inscription : octobre 2009
Messages : 63
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 63
Points : 22
Points : 22
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 :
Citation:
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 :
Citation:
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 ?
Sango64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 09h15   #4
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
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.
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 10h03   #5
Membre à l'essai
 
Inscription : octobre 2009
Messages : 63
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 63
Points : 22
Points : 22
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() ?
Sango64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 12h59   #6
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
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 :
1
2
3
 
nom - prenom
DUPONT ulysse
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 14h12   #7
Membre à l'essai
 
Inscription : octobre 2009
Messages : 63
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 63
Points : 22
Points : 22
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 ?
Sango64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2011, 14h18   #8
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
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 ..
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/08/2011, 10h20   #9
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
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
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h43.


 
 
 
 
Partenaires

Hébergement Web