哪个SQL查询更好,MATCH AGAINST还是LIKE?

70

为了在任意列“foo_desc”和“bar_desc”中搜索同时包含关键词“foo”和“bar”的行,我会做如下操作:

SELECT * 
FROM t1 
WHERE MATCH (t1.foo_desc, t2.bar_desc) AGAINST ('+foo* +bar*' IN BOOLEAN MODE)
或者
SELECT * 
FROM t1 
WHERE (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%foo%') AND (CONCAT(t1.foo_desc, t2.bar_desc) LIKE '%bar%')

我认为上一个查询的缺点是性能问题。

好处是LIKE查询可以找到'MATCH AGAINST'无法找到的'xxfoo'。

哪种方法更好,或者是否有更好的解决方案?

1个回答

69

更新

MySQL 5.6 版本开始,InnoDB 表格支持使用 Match... Against


第一个选项使用全文索引查询那些列时在 MyISAM 表格上效果更好。而另一个选项需要在每一行上进行字符串连接并比较,进行全表扫描。

LIKE 仅在以下情况下高效:

  • 对于某一列进行操作(不适用函数结果,除非你的特定数据库支持函数索引,例如 Oracle,并且你正在使用它们);
  • 对列的开头进行操作(例如 LIKE 'blah%' 而非 LIKE '%blah%');以及
  • 对已经建立索引的列进行操作。

如果以上条件中有任何一项不满足,SQL 引擎执行查询的唯一方法是进行全表扫描。这在大约 10-20K 行以下可以使用,但超过这个数量后很快就变得不可用。

注意: MySQL 上 MATCH 的一个问题是它似乎只匹配整个单词,因此搜索“bla”将无法匹配值为“blah”的列,但搜索“bla*”将会匹配。


22
评论您的笔记:如果您搜索 bla*,MATCH 将返回具有 blah 值的列。 - Wil
5
InnoDB搜索索引的词语最小和最大长度由innodb_ft_min_token_size和innodb_ft_max_token_size定义,而MyISAM搜索索引的最小和最大词语长度则由ft_min_word_len和ft_max_word_len定义。更多信息请参阅https://dev.mysql.com/doc/refman/5.7/en/fulltext-fine-tuning.html。 - Lukas Liesis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接