MySQL-创建和使用全文索引(FullText)

全屏阅读
  • 基本信息

MySQL5.6后,除了 MyISAM 存储引擎,事务型的 Innodb 存储引擎也支持创建和使用全文索引了。

以下为测试过程:

--创建测试表

CREATE TABLE article ( 

id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, 

title VARCHAR(200), 

body TEXT

) engine=innodb;

--插入测试值:

insert into article values(null,'MySQL数据库权威指南','非常不错的书籍,值得一看');

insert into article values(null,'Oracle数据库精选','不妨看看');

insert into article values(null,'SQL Servr 数据库进阶','不容错过');

insert into article values(null,'postgreq 数据库进阶','知道了吗');

--创建复合键title,body全文索引(当然也可以创建单键)

create fulltext index ft_idx on article(title,body) with parser ngram;   --使用 ngram 解释器

--测试是否能走上全文索引的执行计划

mysql> explain select * from article where match(title,body) against('精 妨');

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

| id | select_type | table   | partitions | type     | possible_keys | key    | key_len | ref   | rows | filtered | Extra                         |

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

|  1 | SIMPLE      | article | NULL       | fulltext | ft_idx        | ft_idx | 0       | const |    1 |   100.00 | Using where; Ft_hints: sorted |

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

以上所示,确认可以走上全文索引

--执行使用全文索引的 SQL,看是否能搜索到相关数据:

mysql> select * from article where match(title,body) against('精 妨');

Empty set (0.00 sec)

如上所示,结果是,搜索不到记录,怎么回呢?

往下看:

因为, mysql 5.7.9 中默认  ngram_token_size 参数的默认值为2,如下:

mysql> show variables like '%token%';

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| innodb_ft_max_token_size | 84    |

| innodb_ft_min_token_size | 3     |

| ngram_token_size         | 2     |

+--------------------------+-------+

ngram_token_size 参数指的是,以ngram解释器搜索全文索引时,指定的搜索字符数最小为2个字符(非字节),但以上SQL

select * from article where match(title,body) against('精 妨');  表示 title like '%精%' and  body like '%妨%' 各只有一个字符,所以搜索不到。(意思是和用like 一样,但不能以like方式书写,这样是走不到全文索引的)。

解决方法:

1、修改 ngram_token_size 参数值:

ngram_token_size是静态(只读)参数,必须重启mysql服务,在启动mysql时,指定 --ngram_toke_size=1 的方式启动mysql服务:

[root@dg-st tmp]#mysqld_safe --user=mysql --ngram_token_size=1 &

mysql> show variables like '%token%';

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| innodb_ft_max_token_size | 84    |

| innodb_ft_min_token_size | 3     |

| ngram_token_size         | 1     |      #参数值已经更改为1了

+--------------------------+-------+

2、必须要重建全文索引:

create fulltext index ft_idx on article(title,body) with parser ngram;

这时,再执行以上SQL,就可以查到了:

mysql> select * from article where match(title,body) against('精 妨');

+----+-----------------------+--------------+

| id | title                 | body         |

+----+-----------------------+--------------+

|  3 | Oracle数据库精选      | 不妨看看     |

+----+-----------------------+--------------+

1 row in set (0.01 sec)

另外一种创建全文索引的方式,可以不使用 with ngram 子句,如下:

create fulltext index ft_idx on article(title,body);

这样创建的全文索引最小和最大搜索字符数(分词)受 ft_min_word_len  和 ft_max_word_len 参数的影响,这两个参数也是静态参数,设置后,也必须要重启 mysq 服务才能生效,如下:

mysql>show variables like 'ft_%';

+--------------------------+----------------+

| Variable_name            | Value          |

+--------------------------+----------------+

| ft_boolean_syntax        | + -><()~*:""&| |     --该选项用于全文搜索特殊匹配的表达式

| ft_max_word_len          | 84             |

| ft_min_word_len          | 4              |

| ft_query_expansion_limit | 20             |

| ft_stopword_file         | (built-in)     |

+--------------------------+----------------+

所以,搜索时,全文索引的各个字段必须最小包含4个字符才能搜索到,如下:

mysql>explain select * from article where match(title,body) against('数据库精 不妨看看');

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

| id | select_type | table   | partitions | type     | possible_keys | key    | key_len | ref   | rows | filtered | Extra                         |

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

|  1 | SIMPLE      | article | NULL       | fulltext | ft_idx        | ft_idx | 0       | const |    1 |   100.00 | Using where; Ft_hints: sorted |

+----+-------------+---------+------------+----------+---------------+--------+---------+-------+------+----------+-------------------------------+

1 row in set, 1 warning (0.00 sec)

mysql> select * from article where match(title,body) against('数据库精 不妨看看');

+----+-----------------------+--------------+

| id | title                 | body         |

+----+-----------------------+--------------+

|  3 | Oracle数据库精选      | 不妨看看     |

+----+-----------------------+--------------+

————————————————

版权声明:本文为CSDN博主「Samdy_Chan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Samdy_Chan/article/details/78138420

顶一下
(0)
100%
订阅 回复
踩一下
(0)
100%
» 郑重声明:本文由mpxq168发布,所有内容仅代表个人观点。版权归恒富网mpxq168共有,欢迎转载, 但未经作者同意必须保留此段声明,并给出文章连接,否则保留追究法律责任的权利! 如果本文侵犯了您的权益,请留言。

目前有 0 条留言 其中:访客:0 条, 博主:0 条

给我留言

您必须 [ 登录 ] 才能发表留言!