Quelle requête SQL est la meilleure, MATCH AGAINST ou LIKE?

Pour rechercher dans la firebase database des lignes contenant les deux mots-clés “foo” AND “bar” dans l’une des colonnes “foo_desc” et “bar_desc”, je ferais quelque chose comme:

SELECT * FROM t1 WHERE MATCH (t1.foo_desc, t2.bar_desc) AGAINST ('+foo* +bar*' IN BOOLEAN MODE) 

ou

 SELECT * FROM t1 WHERE (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%foo%') AND (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%bar%') 

Je pense que l’inconvénient de la dernière requête est la performance.

L’avantage est que la requête LIKE trouve “xxfoo” où MATCH AGAINST ne le fait pas.

Quel est le préféré ou existe-t-il une meilleure solution?

Mettre à jour

Depuis MySQL 5.6 et les InnoDB ultérieures, les tables InnoDB supportent Match... Against .


Le premier est bien meilleur. Sur les tables MyISAM, il utilisera un index de texte intégral sur ces colonnes. L’autre effectuera une parsing complète de la table en effectuant un concat sur chaque ligne puis une comparaison.

LIKE n’est efficace que si vous le faites contre:

  • une colonne (ne résultant pas d’une fonction à moins que votre fournisseur de firebase database particulier ne prenne en charge les index fonctionnels – Oracle, par exemple, et que vous les utilisiez);
  • le début de la colonne (c’est-à-dire LIKE 'blah%' par opposition à LIKE '%blah%' ); et
  • une colonne indexée.

Si l’une de ces conditions n’est pas vraie, le seul moyen pour le moteur SQL d’exécuter la requête consiste à effectuer une parsing complète de la table. Cela peut être utilisé sous environ 10-20 mille lignes. Au-delà, il devient rapidement inutilisable.

Note: Un des problèmes avec MATCH sur MySQL est qu’il ne semble correspondre qu’à des mots entiers, donc une recherche de «bla» ne correspondra pas à une colonne avec une valeur de «blah», mais une recherche de «bla *».