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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  [RESOLU] MySQL jointure sur clé primaire LENTE

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[RESOLU] MySQL jointure sur clé primaire LENTE

n°1591810
syl20_44
Posté le 26-07-2007 à 14:01:31  profilanswer
 

Bonjour,
 
Je fais appel à votre aide car j'ai un problème de temps d'exécution sur une requete impliquant une jointure sur une clé primaire.
Je travaille sur une base MySQL.
 
Voici ma base :
 
3 tables :
 
entreprise (id_entr, nom, adresse... )
motcle (id_mot, valeur)
entr_mot (num_entr, num_mot)
 
Il s'agit tout simplement de lier des entreprises avec des mots clés pour faire un petit moteur de recherche. Mon jeu de test comporte 100 000 entreprises, 50 000 mots clés et 1 700 000 tuples dans la table "entr_mot" liant les entreprises et les mots clés.
 
 
A cette structure très simple viennent s'ajouter quelques index :
 
table "entreprise" :
- une clé primaire sur id_entr
 
table "motcle" :
- une clé primaire sur id_mot
- un index fulltext sur valeur (utilisé pour les recherche de type MATCH... AGAINST...)
 
table "entr_mot" :
- un index sur num_entr
- un index sur num_mot
 
 
 
 
Voici la requête que je réalise sur cette base :
 
SELECT num_entr
FROM motscle
INNER JOIN entr_mots ON (id_motcle=num_motcle)
INNER JOIN entreprise ON (id_entr=num_entr)
WHERE MATCH(valeur) AGAINST('+voiture' IN BOOLEAN MODE)
OR MATCH(valeur) AGAINST('+rouge' IN BOOLEAN MODE)
GROUP BY num_entr
HAVING COUNT( num_entr ) = 2
LIMIT 0 , 30
 
C'est à dire que je recherche toutes les entreprises qui sont liées à la fois au mot voiture et au mot rouge.
 
Mon problème :
 
- Cette requête est excessivement lente avec la clé primaire id_mot (20 à 30 secondes).
 
- Si je supprime cette clé primaire ou que je la remplace par un index classique, alors la requête est quasiment instantanée (moins de 0.5 secondes).
 
- Si je ne réalise le test que sur un seul mot clé (donc en supprimant la ligne avec le OR) alors la requête est également instantanée même avec la clé primaire !
 
 
N'hésitez pas à me faire partager vos connaissances. Merci pour votre aide.


Message édité par syl20_44 le 26-07-2007 à 17:23:10
mood
Publicité
Posté le 26-07-2007 à 14:01:31  profilanswer
 

n°1591820
rufo
Pas me confondre avec Lycos!
Posté le 26-07-2007 à 14:07:25  profilanswer
 

Je me demande si t'aurais pas intérêt à mettre un seul index dans ta table entr_mot qui serait composé des 2 clés étrangères...

n°1591821
rufo
Pas me confondre avec Lycos!
Posté le 26-07-2007 à 14:07:53  profilanswer
 

t'as fait un explain de ta requête pour voir ce que fait mysql?

n°1591827
anapajari
s/travail/glanding on hfr/gs;
Posté le 26-07-2007 à 14:13:38  profilanswer
 

le double match against est inutile et pourrit tes perfs ( tu te frappes deux fois le parcours de ta table et par consequence de la table de liaison pour rien) et ton"+" ne sert également à rien vu qu'il n'y a qu'un seul mot.
Tu peux l'écrire ainsi:

Code :
  1. match(valeur) against ('(rouge voiture)' IN BOOLEAN mode)
 

essaye déjà avec ça on verra ce que ça donne :o

Message cité 1 fois
Message édité par anapajari le 26-07-2007 à 14:15:00
n°1591864
syl20_44
Posté le 26-07-2007 à 14:51:22  profilanswer
 

rufo a écrit :

Je me demande si t'aurais pas intérêt à mettre un seul index dans ta table entr_mot qui serait composé des 2 clés étrangères...


 
J'avais fais l'essai mais les résultats étaient déplorables et c'est finalement assez logique car les deux jointures se basent sur les 2 index de manière distincte et non sur un index double.

n°1591871
syl20_44
Posté le 26-07-2007 à 14:57:41  profilanswer
 

anapajari a écrit :

le double match against est inutile et pourrit tes perfs ( tu te frappes deux fois le parcours de ta table et par consequence de la table de liaison pour rien) et ton"+" ne sert également à rien vu qu'il n'y a qu'un seul mot.
Tu peux l'écrire ainsi:

Code :
  1. match(valeur) against ('(rouge voiture)' IN BOOLEAN mode)


 
essaye déjà avec ça on verra ce que ça donne :o


 
 
Je viens d'essayer ta proposition et ça me semble tout bon. Ce qui m'étonne c'est que j'avais pensé à cette solution et les résultats retournés ne correspondaient pas à ce que je voulais. Cependant à force de faire des tests, j'en perds le nord. Donc je n'avais peut-être pas fais exactement le même test. Je reposterai si je me rend compte qu'il y a un problème.
Est-ce que les parenthèses que tu as mis autour de rouge et voiture jouent un role particulier ? J'ai essayé avec et sans mais pas de différence. Est-ce pour prioriser des mots clés ?
 
En tout cas merci de ton aide

n°1591915
anapajari
s/travail/glanding on hfr/gs;
Posté le 26-07-2007 à 16:07:15  profilanswer
 

non effectivement les parenthèses ne servent strictement à rien et tu dois obtenir les mêmes resultats :o  
Elles ne sont utiles que pour définir des sous-expressions par exemple si tu cherches: voiture et ( bleu ou rouge) ça s'écrit:

Code :
  1. +voiture +(bleu rouge)


mais là vu qu'il n'y a que ça dans la pattern, c'est totalement inutile.

n°1591965
syl20_44
Posté le 26-07-2007 à 17:22:35  profilanswer
 

Ah d'accord très bien.
merci beaucoup pour ton aide.


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

  [RESOLU] MySQL jointure sur clé primaire LENTE

 

Sujets relatifs
[RESOLU] exec -> exit php[Résolu] Affichage variable de champs texte en Dreamweaver
[MySQL]Installation Drivers ODBC sous Vista en lignes de commandes[MYSQL] Update un peu tordu
Fenêtre generées "load" "save" automatiquement en pythonQT # Resolu #MySQL: UTF8 vs. latin_swedish & error 1406
[Résolu] [SQL] comment afficher un grand nombre ?[résolu] Exécuter une requête à partir d'un champ
[VB 2005] Utilisation de Base de donnée MySQL 
Plus de sujets relatifs à : [RESOLU] MySQL jointure sur clé primaire LENTE


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