【关于全文索引】聊一聊MySQL中的全文索引

前提

MySQL版本 5.7.29
数据库名 test

创建表

创建一个article表,仅包含两个字段,一个主键ID,一个是TEXT类型的body

create table article( 
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
body TEXT, 
PRIMARY KEY(id));

插入数据

mysql> select * from article;
+----+--------------------------------+
| id | body                           |
+----+--------------------------------+
|  1 | hello world, I am jack         |
|  2 | What a good day, are you happy |
|  3 | nine years old                 |
|  4 | I like you very much           |
|  5 | some one like yout not me      |
+----+--------------------------------+
5 rows in set (0.00 sec)

创建全文索引

create FULLTEXT INDEX ft ON article(body);

设置参数来查看分词信息

mysql> set global innodb_ft_table = 'test/article';

mysql> select * from information_schema.INNODB_FT_INDEX_TABLE;
+-------+--------------+-------------+-----------+--------+----------+
| WORD  | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+-------+--------------+-------------+-----------+--------+----------+
| day   |            4 |           4 |         1 |      4 |       12 |
| good  |            4 |           4 |         1 |      4 |        7 |
| happy |            4 |           4 |         1 |      4 |       25 |
| hello |            3 |           3 |         1 |      3 |        0 |
| jack  |            3 |           3 |         1 |      3 |       18 |
| like  |            6 |           7 |         2 |      6 |        2 |
| like  |            6 |           7 |         2 |      7 |        9 |
| much  |            6 |           6 |         1 |      6 |       16 |
| nine  |            5 |           5 |         1 |      5 |        0 |
| not   |            7 |           7 |         1 |      7 |       19 |
| old   |            5 |           5 |         1 |      5 |       11 |
| one   |            7 |           7 |         1 |      7 |        5 |
| some  |            7 |           7 |         1 |      7 |        0 |
| very  |            6 |           6 |         1 |      6 |       11 |
| world |            3 |           3 |         1 |      3 |        6 |
| years |            5 |           5 |         1 |      5 |        5 |
| you   |            4 |           6 |         2 |      4 |       21 |
| you   |            4 |           6 |         2 |      6 |        7 |
| yout  |            7 |           7 |         1 |      7 |       14 |
+-------+--------------+-------------+-----------+--------+----------+
19 rows in set (0.01 sec)

记录了分词出现的文档ID、position,重复的分词会出现多行信息

限制

  1. 每张表只能有一个全文检索的索引
  2. 由多列组成的全文索引列必须有相同的字符集和排序规则
  3. 不支持没有单词限定符的语言,比如中文、日语。

查询方式

假设我们要查询body字段中带有ou的信息
假设我们不用全文索引的方式查询,可以使用如下的语句

mysql> select * from article where body like '%ou%';
+----+--------------------------------+
| id | body                           |
+----+--------------------------------+
|  2 | What a good day, are you happy |
|  4 | I like you very much           |
|  5 | some one like yout not me      |
+----+--------------------------------+
3 rows in set (0.01 sec)

就算我们对body字段索引,这句话的查询也不会使用到索引

假设我们采用全文索引的方式查询,可以使用如下的语句

mysql> select * from article 
mysql> where MATCH(body) 
mysql> AGAINST('You' IN NATURAL LANGUAGEE MODE);
+----+--------------------------------+
| id | body                           |
+----+--------------------------------+
|  2 | What a good day, are you happy |
|  4 | I like you very much           |
+----+--------------------------------+
2 rows in set (0.01 sec)

其表明的语义为 查询带有 you 这个word的body所在的行信息

在使用MATCH函数进行全文检索的查询时,有四种模式,上面演示的是第一种模式IN NATURAL LANGUAGEE MODE,这也是默认的模式,因此上面的语句,可以写为
select * from article where MATCH(body) AGAINST('You')

查看查询计划

mysql> EXPLAIN select * from article where MATCH(body) AGAINST('You');
+----+-------------+---------+------------+----------+---------------+------+---------+-------+------+----------+-------------------------------+
| id | select_type | table   | partitions | type     | possible_keys | key  | key_len | ref   | rows | filtered | Extra                         |
+----+-------------+---------+------------+----------+---------------+------+---------+-------+------+----------+-------------------------------+
|  1 | SIMPLE      | article | NULL       | fulltext | ft            | ft   | 0       | const |    1 |   100.00 | Using where; Ft_hints: sorted |
+----+-------------+---------+------------+----------+---------------+------+---------+-------+------+----------+-------------------------------+
1 row in set, 1 warning (0.00 sec)

可以看到这句话使用了全文索引字段ft进行了查询。

你可能感兴趣的:(mysql,mysql,索引,innodb)