MySQL5.7建立全文索引与基本使用

全文 使用 索引 模式 建立 数据 titlebody 设置 结果 分词 编程技术
发布日期 2022-11-19 更新日期 2022-11-19 阅读次数 165 文章字数 2.2k

从MySQL 5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。

查看数据库版本:

select version() from dual;

全文检索在MySQL中,只有MyIsam和InnoDB引擎支持。

创建全文索引

如果要导入大量数据的情况下,通常推荐先把数据导入表,然后添加全文索引:

ALTER TABLE article ADD FULLTEXT INDEX ft_index (title, body) WITH PARSER ngram;

ngram就是一段文字里面连续的n个字的序列。ngram全文解析器能够对文本进行分词,每个单词是连续的n个字的序列。例如,用ngram全文解析器对“生日快乐”进行分词:

n=1: '生', '日', '快', '乐' 
n=2: '生日', '日快', '快乐' 
n=3: '生日快', '日快乐' 
n=4: '生日快乐'

(mysql字段,认为非字母数字,都是分词符,比如:a|b,那么就已经认为a和b是一个词,在分词时就会拆分出来)

MySQL 中使用全局变量ngram_token_size来配置ngram中n的大小,它的取值范围是1到10,默认值是2。通常ngram_token_size设置为要查询的单词的最小字数。如果需要搜索单字,就要把ngram_token_size设置为1。在默认值是2的情况下,搜索单字是得不到任何结果的。

修改MySQL配置文件:(my.ini)
[mysqld] 
ngram_token_size=2

查看设置

show variables like '%ngram_token_size%';

全文检索模式

常用的全文检索模式有两种:

  • 自然语言模式(默认模式,不支持操作符)
  • boolean 模式(支持使用操作符,比如 +,-等语法)

不加操作符:表示该词是可选的,含有该词相关性将更高(如 against(‘安卓 分类’) in boolean mode)

+ :一定要有该关键词(不含有的数据条目将忽略)

- :不可以有该关键词(排除指定关键词,含有该词的条目将忽略)

> :提高该词的权重(影响结果排序)

< :降低该词的权重

~ :将该关键词权重由正转负(含有该词的条目,将降低权重排在后面)

* :关键字后面,表示通配符

 

“” :双引号括起来表示为一个短句(可用来解决空格短句问题,如 against(’“安卓 分类”’ in boolean mode),此处"安卓 分类"是一个不可拆分的短句,而不是搜索含有安卓或分类两词的结果)

查询示例:(默认模式)

SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带');

该操作相当于:(显示指定模式)

SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('一路 一带' IN NATURAL LANGUAGE MODE);

使用 boolean 模式,更精确的控制:

// 必须包含"腾讯",但是不能包含"通讯工具"
SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('+腾讯 -通讯工具' IN BOOLEAN MODE);

注意:

  • MATCH (columnName) AGAINST ('keywords')。MATCH()函数使用的字段名,必须要与创建全文索引时指定的字段名一致。也就是说,建立全文索引时,指定了(title, body)就必须是这两个一起,如果只想 match ( title ),则需要单独再建立一个全文索引在 title 上,其他同理。
  • 另外多个字段不能跨表,也就是  title ,body 应该在一张表上。

返回结果的排序?

上面的示例返回结果会自动按照相关性排序,相关性高的在前面。相关性的值是一个非负浮点数,0表示无相关性。

// 获取相关性的值,按 score 降序排序
SELECT id,title,
MATCH (title,body) AGAINST ('手机' IN NATURAL LANGUAGE MODE) AS score
FROM articles
ORDER BY score DESC;

另外这里有个坑,也就是默认情况下,如果不 limit ,是返回所有数据的,即使它的 score 为 0。

查询作为条件:

SELECT * FROM bp3_cache_file where MATCH (path) AGAINST ('美女' IN NATURAL LANGUAGE MODE);

select * from bp3_cache_file where path like '%美女%';

作为条件时,就和 like 相似,测试了一下当前 16w 行数据,执行的结果分别是:0.6秒、0.8秒。

考虑设置大一些的缓存(设置为20%可用ram):

show variables like 'key_buffer%';

得到的结果 /1024/1042 ,即可知道为多少 mb,一般是 32 mb或128mb,可考虑增加这个值(对MyIsam引擎有效)

对 innodb 引擎,该参数是:innodb_buffer_pool_size (设置为 70% 可用ram)

临时设置:(或修改 my.cnf)

set global key_buffer_size=512*1024*1024;

最佳实践

1h2g服务器(centos7),使用MySQL5.7.31,使用InnoDB引擎,单表2000万记录(单表体积2g),全文检索(N-gram)单字段。搜索(自然语言模式)响应速度0.3-0.4秒(同等 like,十几秒或几十秒)。

如果数据再大,全文检索性能可能断崖式下跌,此时的性能瓶颈容易发生在cpu和内存。

在不同版本的MySQL,不同系统,不同cpu或内存,都会影响全文检索的速度,2000w数据,即使是1h2g这样的最低配置,仍毫无压力,效果非常棒(能自动分词,比如输入一个句子,自动拆分为不同的单词并自动搜索,响应速度也是绝佳,小型的搜索引擎)。


文章作者: 朱丰华

文章链接: https://smart.52dixiaowo.com/blog/post-52.html

版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。

全文 使用 索引 模式 建立 数据 titlebody 设置 结果 分词

发表评论

相关推荐
朱丰华   |   1年前   |   sed · 文件

Shell 指定行处理head、tail、sed

167    评论    点赞
朱丰华   |   1年前   |   php · 字符 · 正则

php正则表达式原生字符

95    评论    点赞
朱丰华   |   1年前   |   文件 · linux · 修改

linux文件的三个时间atime,mtime,ctime分别表示什么?

292    评论    点赞
朱丰华   |   1年前   |   php · api · 扩展 · 执行

php sapi生命周期

100    评论    点赞
朱丰华   |   1年前   |   php · 图片

php根据图片内容【魔术数字】,识别图片的类型

311    评论    点赞
朱丰华   |   1年前   |   浏览器 · cookie

基于浏览器的自动获取cookie方案

143    评论    点赞
朱丰华   |   1年前   |   chrome · 截图 · headless

chrome headless模式网页截图,把html转图片

284    评论    点赞
朱丰华   |   1年前   |   chrome

chrome headless在命令行把html生成pdf

140    评论    点赞
朱丰华   |   2年前   |   字符 · 全文 · 检索 · 搜索 · mysql · 单个 · 搜素 · 匹配 · 使用 · 分割

mysql全文检索单个字符搜素

97    评论    点赞
朱丰华   |   2年前   |   普通 · 索引 · 最大 · 长度 · MySQL · 设置 · 可以 · 如果

MySQL普通索引最大长度

101    评论    点赞
朱丰华   |   2年前   |   分词 · php · 使用 · 结巴 · 中文 · seg_list=Jieba · var_dump · seg_list · Jieba · cut

php使用结巴分词【中文分词】

139    评论    点赞
朱丰华   |   2年前   |   全文 · 检索 · 关键字 · 索引 · 数据 · 倒序 · 情况 · 条件 · 搜索 · 文档

全文检索什么情况下会慢?为什么慢?全文检索的正确使用方式。

103    评论    点赞
朱丰华   |   2年前   |   注册 · 模式 · 冲突 · 设计 · 一个

设计模式,注册者模式防冲突

61    评论    点赞
朱丰华   |   2年前   |   > · this · php · 使用 · 并发 · 文件 · 解决 · 问题 · db · 处理

php使用文件锁解决并发问题

91    评论    点赞
朱丰华   |   2年前   |   SaaS · php · 基于 · 平台 · 探讨 · 服务 · 成本

基于php的SaaS平台探讨

102    评论    点赞
朱丰华   |   2年前   |   索引 · MySQL · 选择性 · 开头

MySQL索引选择性差,不走索引

63    评论    点赞
朱丰华   |   2年前   |   匹配 · MySQL · 正则 · 函数 · 字符 · 系列 · regexp · 例如 · like · 位置

MySQL系列之正则函数regexp

113    评论    点赞
{{item.author_name}}   |   {{new Date(item.date*1000).log()}}   |   {{it}} ·

{{item.title}}

{{item.uv}}    评论    点赞