Search in fulltext

Search in fulltext - SQL/NoSQL - Programmation

Marsh Posté le 17-11-2010 à 11:03:43    

Hello,  
 
J'ai une petite question MySQL, au sujet de recherches dans un champ TEXT. J'ai une table (dont malheureusement je ne peux modifier la structure) qui contient un champ texte ; nommons-le "pe". Celui-ci possède un index de type fulltext.
 
Typiquement ce champ contient : 1,2,3
Une requête avec un "FIND_IN_SET", pour rechercher toutes les entrées contenant "2" p.ex. fonctionne parfaitement bien, cependant c'est très très lent (visiblement ça n'utilise pas l'index). Exemple :

Code :
  1. SELECT * FROM mytable WHERE FIND_IN_SET('2', pe);


 
L'idée serait alors d'utiliser un match against :

Code :
  1. SELECT * FROM mytable WHERE MATCH (pe) AGAINST ('+"2"+' IN BOOLEAN MODE);


 
Or les inconvénients de cette méthode sont :

  • si on recherche dans 1,2,3 : pas de résultats, or dans 2,3,4 ou 3,4,2 ça fonctionne ;
  • si on recherche dans 1,222,3 : il trouve aussi un résultat.


Mes questions : comment limiter la recherche à un mot entier, dans une liste séparée par virgule avec match/against ? Y a-t-il aussi rapide, mais avec une autre fonction (sachant toujours que je ne peux pas modifier la structure de la table) ?
Merci beaucoup pour votre aide.


---------------
Un être en tant qu'être ne pourrait-il pas être autre qu'il n'est s'il n'explique pas lui-même son être ?
Reply

Marsh Posté le 17-11-2010 à 11:03:43   

Reply

Marsh Posté le 17-11-2010 à 14:00:45    

sans modifier la structure de la table, ça va etre difficile de faire mieux
A défaut de modifier cette structure,est ce que tu peux faire une table a côté qui explose le champ pe ? le tout alimenté par des trigger en cas de modification/insertion/suppression sur la table parent

 

pour la seconde possibilité, peut etre que tu peux le corriger comme ça :  

Code :
  1. SELECT * FROM mytable WHERE
  2. pe LIKE '2,%' // 2 est en premier
  3. OR pe LIKE '%,2,%' // 2 est  au milieu
  4. OR pe LIKE  '%,2'  //2 est  à la fin
  5. OR pe = 2  // 2 est tout seul


mais c'est sale

Message cité 1 fois
Message édité par flo850 le 17-11-2010 à 14:04:20
Reply

Marsh Posté le 17-11-2010 à 16:25:57    

flo850 a écrit :

sans modifier la structure de la table, ça va etre difficile de faire mieux  
A défaut de modifier cette structure,est ce que tu peux faire une table a côté qui explose le champ pe ? le tout alimenté par des trigger en cas de modification/insertion/suppression sur la table parent
 
pour la seconde possibilité, peut etre que tu peux le corriger comme ça :  

Code :
  1. SELECT * FROM mytable WHERE
  2. pe LIKE '2,%' // 2 est en premier
  3. OR pe LIKE '%,2,%' // 2 est  au milieu
  4. OR pe LIKE  '%,2'  //2 est  à la fin
  5. OR pe = 2  // 2 est tout seul


mais c'est sale


 
Effectivement, c'est pas très joli. Il faut que l'insiste lourdement pour arriver à faire changer cette structure et créer une table de relation... (le champ "pe" contenant des id...)


---------------
Un être en tant qu'être ne pourrait-il pas être autre qu'il n'est s'il n'explique pas lui-même son être ?
Reply

Marsh Posté le 17-11-2010 à 16:34:26    

J'ai pas benché mais je dirais aussi qu'une requête avec LIKE "%...%" ne va pas être d'une rapidité exemplaire, parce que là aussi pas d'indexes utilisés :(


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 17-11-2010 à 16:55:20    

c'est super couteux, mais je ne sais pas ce que ça donne par rapport à find_in_set
 
like 'bidule%' utilise les index, mais aps le reste

Reply

Marsh Posté le 18-11-2010 à 12:13:40    

Sans avoir benché, j'aurais tendance à dire qu'une fonction implantée dans SQL (et donc très probablement, implémentée de manière optimale) sera de toutes façons plus rapide que de tenter de l'émuler par une suite de commandes (surtout que 2 d'entre elles font un scan table)


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 18-11-2010 à 14:43:17    

flo850 a écrit :

c'est super couteux, mais je ne sais pas ce que ça donne par rapport à find_in_set
 
like 'bidule%' utilise les index, mais aps le reste


 
C'est kifkif :)


---------------
Un être en tant qu'être ne pourrait-il pas être autre qu'il n'est s'il n'explique pas lui-même son être ?
Reply

Marsh Posté le 03-12-2010 à 17:27:36    

avec les expressions régulières ça irait pas un poil plus vite (à écrire et à traiter par la BDD) :
 
mysql> SELECT "hfr" REGEXP "^r.*";              
mysql> SELECT "forum.hardware.fr\nforum" REGEXP "^r.*";          


---------------
Don't fuck me, I'm anonymous.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed