对于刚使用mysql全文索引搜索的童鞋,第一个疑惑可能就是,为什么我搜索xx结果不显示呢?明明我数据里面有。这个问题有很多种原因,其中最常见的就是ft_min_word_len(最小搜索长度)导致的。

准备测试数据如下

CREATE TABLE mysql_fulltext
(id BIGINT UNSIGNED AUTO_INCREMENT,
text_info VARCHAR(1000) NOT NULL,
PRIMARY KEY(id),
FULLTEXT(text_info)
)ENGINE=MYISAM DEFAULT CHARSET utf8 COMMENT 'mysql全文索引测试表';

INSERT INTO `mysql_fulltext`(text_info)  VALUES ('a'),('b'),('c'),('aa'),('bb'),('cc'),('aaa'),('bbb'),('ccc'),('aaaa'),('bbbb'),('cccc');

使用如下语句进行搜索

SELECT * FROM `mysql_fulltext` WHERE MATCH(text_info) AGAINST('a');
SELECT * FROM `mysql_fulltext` WHERE MATCH(text_info) AGAINST('aa');
SELECT * FROM `mysql_fulltext` WHERE MATCH(text_info) AGAINST('aaa');

按照我们的惯性思维,应该会显示四条数据才对;但结果却是一条数据都没有。


但是我们执行

SELECT * FROM `mysql_fulltext` WHERE MATCH(text_info) AGAINST('aaaa');

却有结果如下:

wKiom1T9AeDgHDyJAAAXCki0VZE494.jpg



我们看一下全文索引相关的参数设置。

SHOW GLOBAL VARIABLES LIKE '%ft_%';

wKioL1T9Ab_xjt5FAACi7QKAEtg283.jpg

5.6之前myisam的全文索引,需要调节的参数相对来说比较少,只有以上五个。

ft_boolean_syntax:全文索引分词关键字,不能更改,为内置变量
ft_max_word_len:最大分词长度,一般情况下不需要更改
ft_min_word_len:最小分词长度,一般修改为1
ft_query_expansion_limit:不明觉厉的一个参数,基本上不需要设置
ft_stopword_file:全文停止词

我们发现ft_min_word_len为4,默认是该值。也就是说,mysql fulltext只会对4个字或者4个字以上的关键字进行建立索引操作。而刚刚搜索的'a','aa','aaa'关键字长度都小于4。


全文索引相关的参数都无法进行动态修改,我们需要在/etc/my.cnf添加参数ft_min_word_len=1,并且重启mysql服务器,重启完毕之后,对应表执行repair操作。理论上,涉及到ft_相关参数修改的,都需要重启服务器,并且修复所有含有fulltext索引的表。

使用如下sql语句寻找含有fulltext索引的表

SELECT DISTINCT CONCAT('repair table ',table_schema,'.',table_name,' quick;') FROM information_schema.`STATISTICS` WHERE index_type='fulltext'

我们修复mysql_fulltext后,执行查询语句

REPAIR TABLE mysql_fulltext QUICK;
SELECT * FROM `mysql_fulltext` WHERE MATCH(text_info) AGAINST('a');

以上查询,能查询到对应的数据。

wKioL1T9Bo_TuEPuAAAYuQ3Frgk261.jpg

但是疑问来了,为什么我查询关键字'a',却无法搜索出'aa','aaa','aaaa'关键字对应的行呢?

有兴趣的童鞋可以自行思考一下,或者关注我后续的mysql全文索引相关文章。