Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2547 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Différence entre deux Requêtes

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Différence entre deux Requêtes

n°1954111
The Murder​er
Posté le 30-12-2009 à 23:01:00  profilanswer
 

Bonjour à tous,
 
J'aimerais savoir la différence entre ces deux requête mysql :
 
- SELECT * FROM produit P, rubrique R WHERE P.id_produit = R.id_produit AND R.id_rubrique = 'legumes' ;
 
- SELECT * FROM produit WHERE id_produit IN (SELECT id_produit FROM rubrique WHERE id_rubrique = 'legumes') ;
 
Peut-on également faire une sous-requête sur une même table ?
 
- SELECT id_produit FROM produit WHERE id_produit IN (SELECT id_produit FROM produit WHERE description_produit = 'pain') ;
 
Cela paraît ridicule mais ça me permettrais d'éviter de mettre deux WHERE à la suite ce qui n'est pas possible il me semble.
 
Merci pour vos réponses.
 

mood
Publicité
Posté le 30-12-2009 à 23:01:00  profilanswer
 

n°1954120
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 30-12-2009 à 23:55:59  profilanswer
 

oh putain [:mlc]
si tu veux éviter les WHERE à la con, renseigne toi sur les jointures via le mot clé JOIN, et recherche mes interventions sur la cat SQL qui fustigent les jointures par WHERE


---------------
J'ai un string dans l'array (Paris Hilton)
n°1954140
MagicBuzz
Posté le 31-12-2009 à 09:16:26  profilanswer
 

Cf le lien de ma signature ( :ange: )


Message édité par MagicBuzz le 31-12-2009 à 09:16:32
n°1954157
anapajari
s/travail/glanding on hfr/gs;
Posté le 31-12-2009 à 10:03:50  profilanswer
 

The Murderer a écrit :

SELECT id_produit FROM produit WHERE id_produit IN (SELECT id_produit FROM produit WHERE description_produit = 'pain') ;


[:prozac]  
Tu te rends compte que ta requête revient à  

Code :
  1. SELECT id_produit FROM produit WHERE description_produit = 'pain'


 

The Murderer a écrit :

ça me permettrais d'éviter de mettre deux WHERE à la suite ce qui n'est pas possible il me semble.


Peux-tu developper ?


---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1954161
fred777888​999
Posté le 31-12-2009 à 10:16:04  profilanswer
 

Harkonnen a écrit :

oh putain [:mlc]
si tu veux éviter les WHERE à la con, renseigne toi sur les jointures via le mot clé JOIN, et recherche mes interventions sur la cat SQL qui fustigent les jointures par WHERE


+1
Where c'est pour les restrictions, join pour les jointures.
La bonne requete (la premiere) est donc :

Code :
  1. SELECT *
  2. FROM produit P JOIN rubrique R  ON P.id_produit = R.id_produit
  3. WHERE  R.id_rubrique = 'legumes' ;


La deuxieme est a eviter, les perfs du 'in' equivallent au or sont degeulasses en general et peuvent ne pas utiliser d'index. Si tu tiens quand meme a l'utiliser, mets au moins un distinct dans le sous select ou plutot prefere utiliser un clause 'exists' souvent moins penalisante :

Code :
  1. SELECT *
  2. FROM produit P
  3. WHERE EXISTS ( SELECT NULL FROM rubrique R WHERE p.id_produit = r.id_produit and id_rubrique = 'legumes') ;


mais c'est nettement moins performant qu'une jointure.
Quand a la derniere, anapajari a tout dit, il est souvent plus simple d'enrichir la clause where que de faire des auto-sous-jointures a la mord moi le noeud.

n°1954166
MagicBuzz
Posté le 31-12-2009 à 10:18:52  profilanswer
 

Pour la diff entre IN et EXISTS, je tenais le même discourt.
Finalement, après différents tests (cf. ma signature) j'ai du admettre que Oracle et Microsoft tout du moins, on particulièrement beaucoup travaillés sur le IN, qui est étonnamment souvent plus rapide que le EXISTS (moi aussi ça m'a laissé sur le derrière)

n°1954190
fred777888​999
Posté le 31-12-2009 à 11:25:42  profilanswer
 

Oui, c'est en partie vrai car les in sont automatiquement transformes en 'union' depuis un certain temps par ces deux systemes.  
Par contre, si tu lis bien le sujet, c'est du mysql et mysql est une vraie merde de ce cote.
Compare une requete avec des or et une union (meme perfs oracle et sqlserveur a peu de chose pres) aux variantes mysql et pleure si tu utilise ce dernier.
 
==> Edit grammaire et orthographe trop pitoyables pour rester en l'etat meme si ce n'est pas encore parfait.

Message cité 1 fois
Message édité par fred777888999 le 31-12-2009 à 11:28:39
n°1954207
anapajari
s/travail/glanding on hfr/gs;
Posté le 31-12-2009 à 11:55:20  profilanswer
 

fred777888999 a écrit :

les perfs du 'in' equivallent au or sont degeulasses en general et peuvent ne pas utiliser d'index.


fred777888999 a écrit :

Oui, c'est en partie vrai car les in sont automatiquement transformes en 'union' depuis un certain temps par ces deux systemes.


Source ou explication pour ces deux points, ça m'interesse :o  


---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1954233
The Murder​er
Posté le 31-12-2009 à 13:48:03  profilanswer
 

anapajari a écrit :


[:prozac]  
Tu te rends compte que ta requête revient à  

Code :
  1. SELECT id_produit FROM produit WHERE description_produit = 'pain'


 


 

anapajari a écrit :


Peux-tu developper ?


 
Merci pour vos réponses !!
 
En fait, j'ai une requête assez complexe à ecrire et je suis un peu perdu.
 
J'aimerais joindre plusieurs tables :  
 
-Table rubrique --> id_rubrique//nom_rubrique
-Table rubrique_sup --> id_rubrique//id_rub_sup
-Table rubriques_produits --> id_rubrique//id_produit
-Table produit --> id_produit//libelle_produit//prix_produit
 
J'aimerais connaitre le nom des rubriques (nom_rubrique) ayant pour rubrique supérieure 2 (id_rub_sup = '2') et contenant tout les produits répondants a un certain mot clé.
 
J'ai essayé de l'ecrire comme ceci :
 
 SELECT * FROM rubrique R JOIN rubrique_sup RS ON R.id_rubrique = RS.id_rubrique  
 WHERE RS.id_rub_sup = '.$idsup.' AND R.id_rubrique IN (SELECT RP.id_rubrique FROM rubriques_produit RP JOIN rubrique R ON RP.id_rubrique = R.id_rubrique WHERE RP.id_rubrique  
 IN (SELECT DISTINCT id_rubrique FROM rubriques_produit WHERE id_produit  
 IN (SELECT DISTINCT id_produit MATCH (libelle_produit) AGAINST ('.$rech.')
 FROM produit WHERE MATCH (libelle_produit) AGAINST ('.$rech.'))))' ;  
 
Je ne sais pas quand utiliser des IN et quand utiliser des JOIN sachant que cela se ressemble j'ai l'impression.  
 
De plus je veux la jointure des rubriques ayant telle rub_sup et des rubriques ayant tels produits et je ne pense pas ici que le AND soit le bon mot.
 
Merci pour votre aide.

n°1954237
fred777888​999
Posté le 31-12-2009 à 14:09:02  profilanswer
 

Ben c'est que des jointures que je vois dans ton truc, la requete est elementaire...

Code :
  1. SELECT R.*
  2. FROM rubrique R
  3. JOIN rubrique_sup s ON s.id_rubrique = R.id_rubrique
  4. JOIN rubriques_produit RP ON rp.id_rubrique = R.id_rubrique
  5. JOIN produit P ON p.id_produit = rp.id_produit
  6. WHERE S.id_rub_sup = 2
  7. AND MATCH(p.libelle_produit) AGAINST '$rech'


ou alors qq chose de simple m'as echape mais je ne vois pas quoi ?

mood
Publicité
Posté le 31-12-2009 à 14:09:02  profilanswer
 

n°1954238
fred777888​999
Posté le 31-12-2009 à 14:09:43  profilanswer
 

Tu peux ajouter un distinct pour eviter d'avoir les rubriques en doublons, ce sera plus propre...

n°1954241
MagicBuzz
Posté le 31-12-2009 à 14:14:47  profilanswer
 

Code :
  1. SELECT r.nom, count(p.*) nb
  2. FROM rubrique r
  3. INNER JOIN rubrique_sup rs ON rs.id_rubrique = r.id_rubrique
  4. INNER JOIN rubriques_produit rp ON rp.id_rubrique = r.id_rubrique
  5. INNER JOIN produit p ON p.id_produit = rp.id_produit
  6. WHERE rs.id_rub_sup = $idsup
  7. AND match(p.libelle_produit) against ($rech)
  8. ORDER BY 1 DESC
 

A noter que je ne suis pas sûr de la syntaxe du MATCH() AGAINST() que je n'utilise pas (je travaille jamais sur MySQL)

 

En tout cas, à ce détail près, t'as rien de plus compliqué que ça dans ta requête...

 

Grrrr, grillé par fred :o


Message édité par MagicBuzz le 31-12-2009 à 14:15:15
n°1954244
fred777888​999
Posté le 31-12-2009 à 14:18:47  profilanswer
 

==> surtout tu as oublie le group_by pour ta fonction de comptage, on va mettre ca sur le compte du nouvel an :)

n°1954250
fred777888​999
Posté le 31-12-2009 à 14:38:21  profilanswer
 

anapajari a écrit :


Source ou explication pour ces deux points, ça m'interesse :o  


Si tu as mysql, oracle et/ou sql-serveur, le test est tres facile a faire...

Code :
  1. SELECT * FROM table T WHERE T.clef = 'valeur'


Utilise l'index

Code :
  1. SELECT * FROM table T WHERE T.clef = 'valeur'
  2. UNION
  3. SELECT * FROM table T WHERE T.clef = 'valeur2'


l'utilise aussi

Code :
  1. SELECT * FROM table T WHERE T.clef IN ('valeur', 'valeur1')


ou

Code :
  1. SELECT * FROM table T WHERE ((T.clef = 'valeur') OR (T.clef= 'valeur1'))


fait un magnifique full scan en mysql, mais utilise bien l'index en oracle ou sqlserveur. J'en suis tombe sur le cul quand une des pages d'un de nos sites rammait a mort suite a la modif d'un collegue qui avait rajoute un or sur un colonne de clef primaire.
Ce truc est Ok en oracle depuis la version 8 au moins :)  
Je n'ai pas verifie si c'etait vrai avec tous les moteurs mysql ou seulement celui qu'on utilisait (je ne sais plus lequel c'etait).

n°1954251
anapajari
s/travail/glanding on hfr/gs;
Posté le 31-12-2009 à 14:38:37  profilanswer
 

fred777888999> c'est possible mon explication ou pas ? (cf mon post plus haut), merci :)


---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1954252
fred777888​999
Posté le 31-12-2009 à 14:39:41  profilanswer
 

:) up :)

n°1954254
MagicBuzz
Posté le 31-12-2009 à 14:56:16  profilanswer
 

fred777888999 a écrit :

==> surtout tu as oublie le group_by pour ta fonction de comptage, on va mettre ca sur le compte du nouvel an :)


Et sur le fait que ça doit faire 6 mois que j'ai pas écrit une seule requête :D

n°1954267
anapajari
s/travail/glanding on hfr/gs;
Posté le 31-12-2009 à 15:27:25  profilanswer
 

fred777888999 a écrit :


Si tu as mysql, oracle et/ou sql-serveur, le test est tres facile a faire...
[...]
Je n'ai pas verifie si c'etait vrai avec tous les moteurs mysql ou seulement celui qu'on utilisait (je ne sais plus lequel c'etait).


C'est pas le cas sur une 5.0.37 :o

EXPLAIN EXTENDED select * from maTable where monChamps=1 or monChamps=2;
--
id,  select_type,  table,   type,   possible_keys,  key,   key_len,  ref,   rows,  Extra
1,  'SIMPLE',  'maTable',  'range',  'PRIMARY',  'PRIMARY',  '4',   '',   2,  'Using where'

 

EXPLAIN EXTENDED select * from maTable where monChamps in (1,2);
--
id,  select_type,  table,   type,   possible_keys,  key,   key_len,  ref,   rows,  Extra
1,  'SIMPLE',  'maTable',  'range',  'PRIMARY',  'PRIMARY',  '4',   '',   2,  'Using where'

 

EXPLAIN EXTENDED select * from maTable where monChamps=1 union select * from maTable where monChamps = 2;
--
id,  select_type,  table,   type,   possible_keys,  key,   key_len,  ref,   rows,  Extra
1,  'PRIMARY',  'maTable',  'const',  'PRIMARY',  'PRIMARY',  '4',   'const',  1,  ''
2,  'UNION',  'maTable',  'const',  'PRIMARY',  'PRIMARY',  '4',   'const',  1,  ''
,  'UNION RESULT', '<union1,2>',  'ALL',   '',   '',   '',   '',   ,  ''

 

Par ailleurs sur le point oracle (conversion in => union), j'ai trouvé ça qui montrerait plutot que l'optimizer transforme les in/exists en join (et pas en union)...


Message édité par anapajari le 31-12-2009 à 15:28:13

---------------
Software and cathedrals are much the same - first we build them, then we pray.
n°1954271
fred777888​999
Posté le 31-12-2009 à 15:41:14  profilanswer
 

Effectivement, ton or est correctement fait, mais je peux t'assurer que ce n'etait pas le cas sur l'optimisation qu'on a du faire :( J'en ai donc tire abusivement la conclusion que mysql ne faisait JAMAIS l'optimisation alors que ce n'est visiblement pas le cas.  
Merci de cette precision :)
Pour le second point, oui, bien sur, il faut bien faire une jointure sous la sous-requete avant de faire l'union ensuite pour ramener les deux lignes du exists. Mais je t'accorde volontier que le terme 'transforme en union' est un abus de language juste pour rendre l'idee comprehensible.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Différence entre deux Requêtes

 

Sujets relatifs
Requêtes HTTP en Phython[SQL] Requetes SQL et Jointures
ada différence fonction, procédureProblemes requetes PHP/MySql
Trier résultat de 2 requetes[RESOLU]Plusieurs requetes SQL en une seul sous forme de tableau
Difference entre 2 commandessurveiller les requêtes ou tables modifiées sur MySQL
Difference Online / Offline (player music)[Access] Différence de vitesse INNER JOIN et 2 requetes imbriquées?
Plus de sujets relatifs à : Différence entre deux Requêtes


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR