MySQL全文检索

来自姬鸿昌的知识库
跳到导航 跳到搜索

MySQL5.7之后增加了对中文全文检索的支持,

ALTER table 表名 add fulltext 索引名(title,body) with parser ngram

举例,表结构:

类型 长度
id int 11
phone_no varchar 16
user_name varchar 32
home_address varchar 64
user_desc varchar 512
sex tinyint 4
add fulltext index all_column_full('user_name','home_address','user_desc') parser 'ngram'

ngram 是 MySQL 5.7推出的中文分词解析器,但它的解析比较蠢,过程类似比如:

解析“我是好人”

两个字:我是 是好 好人

三个字:我是好 是好人

四个字:我是好人

解析成上面的分词,然后再形成倒排索引

未启用全文索引和启用全文索引效果对比

未启用全文索引:

like '%内容%' 从600万条数据的表中查询, 大概10秒~20秒;

启用全文索引:

select * from test_user_info where match ('user_name', 'home_address', 'user_desc') against ('二蛋' in boolean mode)

大概100毫秒

MySQL 启用全文索引带来的问题

表中已有600万测试数据,再插入一条数据要花费5分钟时间,有的时候插入快,有的时候插入很慢,插入慢的时候内存会疯狂飙升(因为MySQL在重建索引),

MySQL生成全文索引的实现是空间换时间,生成索引的时间非常慢,建议把数据都插入完毕的时候,再用

repair table tableName

修复一下索引

更新字段时不会实时更新索引

MySQL会定期维护索引,如果 update 或者 insert 正好处于 MySQL 更新索引的时间点,那么操作会非常缓慢

如果一定要用MySQL自带的全文索引

MySQL的全文索引必须要全部存到内存查询才快

在经过分词之后数据膨胀,原本的表数据会变大很多,测试数据来看 1G数据分词全文索引之后占5G内存,ngram分词器默认分词长度为2~10(倒是可以通过配置修改)

结论

MySQL不适合做全文索引的中间件,但如果只针对姓名这种两三个字,数据量又不是特别大,也还可以考虑