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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [SGBD] Décrotter une requête

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[SGBD] Décrotter une requête

n°806228
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 12:19:15  profilanswer
 

Je suis en train de faire un moteur de recherche pour un site. Et vu que j'ai bien la tête dans le c*l ce matin, j'ai l'impression que la requête aurait pu être un peu mieu...
 
SDBG : Oracle 8i (bientôt 9i)
Tout d'abord, voici le modèle des données (mais nan, n'ayez pas peur :ange:) :
http://perso.wanadoo.fr/magicbuzz/mpd_cms.png
 
Pour résumer :
-> Les produits (référence) sont stockés dans la table PRO.
-> Les noms et descriptions des produits sont stockés dans la table PRM.
-> Si un produit n'est pas traduit dans la langue du client, alors on recherche aussi dans la langue anglaise.
-> Un client (sigtie) peut avoir des codes personnalisés pour chacun des produits (table PROTIE)
-> Une version évoluée de la fiche produit peut être présente dans la table NEWS. Dans ce cas, on recherche la "news" qui est dans la langue du produit PRM trouvé (langue du client ou anglais si langue du client pas trouvée)
-> Chaque "news" peut contenir des documents dans la table MED
 
PS: le modèle des données n'est pas tout à fait à jour, il n'est là que pour voir la structure des données, les champs on légèrement évolué.
 
La recherche doit se faire sur tous les "codes" du produit (code client, interne et fournisseur), les différents libélls et les noms des documents associés.
 
Voici la requête que j'ai pondu :


select codpro
from
(
 select allpro.codsoc, allpro.codpro, allpro.codpro || allpro.motcle || allpro.refpro || allpro.nompro || news.header || news.desc1 || news.desc2 || news.desc3 || news.desc4 || news.desc5 || med.title || med.path || allpro.codprotie keywords  
 from med, news,  
  (
  select pro.codsoc, pro.codpro, pro.motcle, pro.refpro, nvl(lng.codlan, eng.codlan) codlan, nvl(lng.nompro || lng.txtpro, eng.nompro || eng.txtpro) nompro, protie.codprotie
  from protie, prm eng, prm lng, pro
  where lng.codsoc(+) = pro.codsoc
  and lng.codpro(+) = pro.codpro
  and lng.codlan(+) = 'FRA'
  and eng.codsoc = pro.codsoc
  and eng.codpro = pro.codpro
  and eng.codlan = 'ENG'
  and protie.codsoc(+) = pro.codsoc
  and protie.sigtie(+) = '520036'
  and protie.codpro(+) = pro.codpro
  ) allpro
 where news.codsoc(+) = allpro.codsoc
 and news.typnew(+) = 'PRO'
 and news.codlan(+) = allpro.codlan
 and news.codpro(+) = allpro.codpro
 and med.codsoc(+) = allpro.codsoc
 and med.tabori(+) = 'PRO'
 and med.cle1(+) = allpro.codpro
 and med.typtie(+) = 'PRO'
 and med.codlan(+) = allpro.codlan
) search
where search.codsoc = 0
and upper(search.keywords) like upper('%papier%')


 
=> Ici, le client francophone d'id 520036 recherche un produit en utilisant le mot-clé "papier"
 
La requête tourne bien, et retourne le résultat attendu en 31 ms (219 ms lorsque la requête n'est pas en cache).
Seulement, actuellement j'ai pas beaucoup de lignes :
 
PRO : 32
PRM : 63
NEWS : 36
MED : 48
PROTIE : 1
 
Dans le futur, je pense avoir ca à peut près :
PRO : 30 000
PRM : PRO * 5 = 150 000
NEWS : PRO * 6 = 180 000
MED : NEWS * 3 = 540 000
PROTIE : 50 000 / 100 * 10 = 5 000
 
C'est pas vraiment la même donne...
Deplus, actuellement, je n'ai qu'un mot clé, à l'avenir, il y en aura certainement beaucoup plus.
 
J'ai écrit cette requête de cette façon plutôt que faire un like sur chaque champ, afin de pouvoir la rendre facilement évolutive, notamment la partie dynamique (ajout de mots clés et de critères de recherche).


Message édité par Arjuna le 26-07-2004 à 12:19:52
mood
Publicité
Posté le 26-07-2004 à 12:19:15  profilanswer
 

n°806262
gizmo
Posté le 26-07-2004 à 12:46:49  profilanswer
 

euh... question bête, ton search.codesoc=0, il vient d'où? C'est un critère de recherche ou une constante?

n°806346
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 14:02:15  profilanswer
 

Constante, mais que je dois conserver au plus haut niveau possible, car il sera d'ici 1 an environ dynamique (gestion multi-société de l'ERP)
 
Il est propagé depuis la sous-sous-requête, sur la table pro, et utilisé pour les jointures avec toutes les autres tables.
 
A noter que je le sors au maximum, car il y a de fortes chances pour que je passe cette requête en vue si ça rame trop.


Message édité par Arjuna le 26-07-2004 à 14:02:58
n°806402
gizmo
Posté le 26-07-2004 à 14:38:58  profilanswer
 

mouais, chuis pas convaincu. A mon avis, même en variable, tu peux le faire remonter dans la sous-requète afin d'avoir moins de résultat retourné à traiter par la suite.
 
Enfin, de toute façon, telle qu'elle est là, ta requète fait trop de boulot. tu fais une jointure à chaque fois avec protie alors qu'il n'est jamais utilisé.
 

n°806411
Beegee
Posté le 26-07-2004 à 14:48:49  profilanswer
 

mets l'explain plan de ta requête actuelle dans le 1er post ;)

n°806479
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 15:25:59  profilanswer
 

Gizmo >  
 
Ben si, protie est utilisé :
" || allpro.codprotie" à la fin du select le plus imbriqué.
 
Sinon, je ne comprends pas le début de ton post. De toute façon, lors de l'éxécution, Oracle n'éxécute pas les requêtes telles qu'elles, tous les filtres sont descendus au plus pas niveau possible, donc le codsoc s'applique jusqu'au plus bas niveau de sous-requête. De ce côté, il n'y a aucun problème, ça ne changera rigoureusement rien.
 
C'est juste la concaténation et le like qui me pose problème, je pense que si je testais champ par champ, ça pourrait être plus rapide, mais je n'en suis pas sûr du tout... C'est surtout là qu'une optimisation serait utile.

n°806489
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 15:27:37  profilanswer
 

Beegee > Hmmm, je vais voir si je peux poster l'explain plan. Rien n'est moins sûr, car je n'ai ni les outils nécessaires ni les droits :/

n°806524
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 15:42:11  profilanswer
 

Au fait, truc que je n'ai pas précisé. CODSOC est un champ systématiquement présent dans toutes les requêtes de la base, il fait partie de la clé unique de chaque table.
Il s'agit du numéro de société rattaché, ce qui permet une gestion multi-société de l'ERP, et à terme du site web.

n°806537
Beegee
Posté le 26-07-2004 à 15:46:55  profilanswer
 

une petite remarque si tu concerves la concaténation de tous les champs : tu risques de trouver des lignes du type :
allpro.codpro = 'totopap'
allpro.motcle = 'ierstata'
 
alors que je ne pense pas que tu les veuilles :D
 
Donc pense à mettre des caractère spéciaux entre chaque couplet de champs concaténés ... ou alors reviens à un like sur chaque champ.
 
L'avantage du like sur chaque champ, c'est quand même de filtrer dès le début les informations, ce qui permet de n'arriver très rapidement qu'à un très petit nombre de lignes manipulées :)

n°806810
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-07-2004 à 18:08:56  profilanswer
 

J'y avais pensé et j'ai modifié en effet, j'ai ajouté des espaces entre chaque champs que je concatène ;)
 
Et il y aura autant de like que de mots saisis, donc plus de problème :)


Message édité par Arjuna le 26-07-2004 à 18:09:10

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

  [SGBD] Décrotter une requête

 

Sujets relatifs
Petit problème de requête...une requete assez compliquée
Limiter le nombre de requete php par minuterequete SQL select like dans un CLOB
Requete Update avec jointure sous SQL SERVEURProblème de date dans requête imbriquée
[MySQL] Requète un peu compliqué...[Socket] Répondre à une requête HTTP
Faire son choix parmis les SGBD Open Source ?[Access] Sauvegarder les résultats d'une requete dans une table
Plus de sujets relatifs à : [SGBD] Décrotter une requête


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