|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
Bonjour,
la situation : j'ai 2 tables qui enregistre des produits et leurs propriétés : cat_product(id_product,libelle) et cat_product_additionnal_properties(id_product,id_champs,value,lang) chaque produit à environ 10 à 20 propriétés additionnelles. La table cat_product_famille enregistre 1 produit dans 1 famille. La table cat_product contient 20 000 lignes et la table cat_product_additionnal_properties contient 320 000 lignes. Je souhaite afficher sur une page tous les produits d'une famille avec leurs propriétés, le tout listé dans un tableau, mais je me heurte à des temps d'execution de ma requete trop élevé lorsqu'il y a plus de 400 produits dans une famille. Et maintenant voici un exemple de requête, cet exemple est particulier car pour cette famille (qui contient 12 000 produits) je dois grouper mes résultats par marque et modèle, qui sont 2 propriétés additionnelles du produit, pour éviter d'afficher 12 000 produits (le group by réduit a 800) Code :
Merci par avance pour votre aide. (Remarque: je bosse sur un CMS payant, la structure de la bdd n'est pas modifiable) |
||
|
|
00
|
|
|
#2 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 655 ![]() |
Bonjour,
Déjà votre group by est mal écrit, en effet vous n'avez que 2 colonnes sur les 4 du select qui sont spécifiés dans la clause group by. Ensuite si vous n'utilisez pas de fonction d'agrégation (count, min, etc) c'est un distinct qu'il faut utiliser. Point suivant, vous avez 3 left outer join qui vont être transformés en inner join car vous mettez dans la clause where des restrictions sur ces tables : utilité des left outer join ? Mise à part ça, il faudrait vérifier que vous avez des index sur toutes les clauses de jointure. Quand tout ceci sera vérifier et si c'est toujours lent il faudra sans doute présenter l'explain de la requête pour qu'une personne puisse l'analiser et proposer une solution (ou pas c'est peut-être le temps de fetch du curseur qui est lent) |
|
|
00
|
|
|
#3 |
![]() ![]() |
1) GROUP BY s'utilise avec des fonctions de regroupement (COUNT, SUM, AVG, MIN, MAX).
Du fait de ton GROUP BY, id_product et traduction_fr seront aléatoires. 2) Mettre une condition de restriction dans le WHERE sur une table externe d'une jointure externe revient à faire une jointure interne. Voir mon blog pour plus d'explication. En l'occurence, je crois que des jointures internes seraient ici suffisantes non ? 3) Si ta requête est longue, commence par vérifier si les tables sont bien indexées, notamment sur les colonnes figurant dans les conditions de jointure. La plupart sont des id donc en principe des clés primaires et étrangères et il y a de fortes chances qu'elles soient indexées. Par contre, la table i18n est plus inquiétante ! Une jointure sur un libellé est contre performant. 4) L'utilisation systématique d'alias courts rend la lecture de la requête plus facile. Dis-nous plus précisément ce que tu cherches à obtenir parce que ton GROUP BY est incohérent. EDIT : Grilled by Punkoff !
__________________
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 ! |
|
00
|
|
|
#4 | ||||
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
bonjour,
merci à vous 2 pour vos réponses rapides, je reviens sur mon problèmes (après un passage sur un autre projet + les vacances qui sont passées par là). J'ai pris note de vos précieuses remarques sur le group by et le left join. J'ai refait quelques tests aujourd'hui en simplifiant ma requête Code :
Les index sont bien créé sur les différents champs de jointure (même sur i18n.shortcut) voici le explain de la requete : Code :
|
||||
|
|
00
|
|
|
#5 | ||||
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 655 ![]() |
Que veut dire long ?
Sinon que donne cette requête ? edit : Code :
Code :
|
||||
|
|
00
|
|
|
#6 |
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
long ça veut dire que la requête dépasse le délai d’exécution.
ta requête est très efficace, délai de 5 à 6 secondes. Je n'aurais jamais pensé l'écrire de cette manière ! par contre je ne comprends pas le Code :
HAVING count(DISTINCT addprop.id_champs) = 3 merci |
|
|
00
|
|
|
#7 |
![]() ![]() |
Si on ne met pas le HAVING, du fait de WHERE addprop.id_champs IN (133, 59, 132), les lignes ayant l'un des trois critères seraient pris en compte. Le HAVING permet de dire qu'on ne prend que les cat_product.id_product ayant 3 adddrop.id_champ différents, c'est à dire les 3 qui sont dans le IN.
__________________
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 ! |
|
00
|
|
|
#8 |
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
ok c'est plus clair pour moi merci
je me rapproche du but toutefois une dernière question : est-ce qu'il est possible avec cette requete de filtrer sur une valeur présente dans addprop.value ? Par exemple si je ne veux retourner que les enregistrements d'une seule marque ? J'ai fait plusieurs tests mais je n'y parviens pas et je ne vois pas comment faire ? |
|
|
00
|
|
|
#9 |
![]() ![]() |
La marque est stockée où ?
Quelle requête as-tu essayé ?
__________________
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 ! |
|
00
|
|
|
#10 | ||
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
je parle de la requête de punkoff
Code :
|
||
|
|
00
|
|
|
#11 | |||||
![]() ![]() |
Ok je n'avais pas bien lu la question.
Citation:
Quand je demandais ceci : Citation:
Citation:
On sort la marque (code 133) du IN et on lui concocte une condition sur mesure : Code :
__________________
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 ! |
|||||
|
00
|
|
|
#12 |
|
Invité de passage
![]() Inscription : novembre 2011 Messages : 6 ![]() |
un grand merci à vous 2 !
grâce à votre aide je vais pouvoir avancer comme je le souhaite. |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com