Décrotter une requête [SGBD] - SQL/NoSQL - Programmation
Marsh Posté le 26-07-2004 à 12:46:49
euh... question bête, ton search.codesoc=0, il vient d'où? C'est un critère de recherche ou une constante?
Marsh Posté le 26-07-2004 à 14:02:15
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.
Marsh Posté le 26-07-2004 à 14:38:58
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é.
Marsh Posté le 26-07-2004 à 14:48:49
mets l'explain plan de ta requête actuelle dans le 1er post
Marsh Posté le 26-07-2004 à 15:25:59
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.
Marsh Posté le 26-07-2004 à 15:27:37
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
Marsh Posté le 26-07-2004 à 15:42:11
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.
Marsh Posté le 26-07-2004 à 15:46:55
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
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
Marsh Posté le 26-07-2004 à 18:08:56
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
Marsh Posté le 26-07-2004 à 12:19:15
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 ) :
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