当前位置: 首页 > MySQL数据库

InnoDB全文索引是什么

时间:2026-01-28 14:10:49

InnoDB全文索引:N-gram Parser

March 26, 2015MySQLShaohua Wang

InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的。但对于像中文,日文和韩文来说,没有这样的分隔符。一个词可以由多个字来组成,所以我们需要用不同的方式来处理。在MySQL 5.7.6中我们能使用一个新的全文索引插件来处理它们:n-gram parser.

什么是N-gram?

在全文索引中,n-gram就是一段文字里面连续的n个字的序列。例如,用n-gram来对”信息系统”来进行分词,得到的结果如下:

N-gram 例子

1
2
3
4
N=1 : '信', '息', '系', '统';
N=2 : '信息', '息系', '系统';
N=3 : '信息系', '息系统';
N=4 : '信息系统';

 如何在InnoDB中使用N-gram Parser?

N-gram parser是默认加载到MySQL中并可以直接使用的。我们只需要在DDL中创建全文索引时使用WITH PARSER ngram。比如,下面的SQL语句在MySQL 5.7.6及更高版本上可以运行。

N-gram DDL示例

1
2
3
4
5
6
7
8
9
mysql > CREATE TABLE articles
(
FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(100),
FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram
) Engine=InnoDB CHARACTER SET utf8mb4;
Query OK, 0 rows affected (0.06 sec)
mysql> # ALTER TABLE articles ADD FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram;
mysql> # CREATE FULLTEXT INDEX ngram_idx ON articles(title) WITH PARSER ngram;

我们引入了一个新的全局变量叫ngram_token_size。由它来决定n-gram中n的大小,也就是词的大小。它的默认值是2,这个时候,我们使用的是bigram。它的合法的取值范围是1到10。现在,我们很自然会想到一个问题:实际应用中应该如何设置ngram_token_size值的大小呢?当然,我们推荐使用2。但是你也可以通过如下这个简单的规则来可以选择任何合法的值:设置到你希望能查询到的最小的词的大小。如果你想查询到单个字,那么我们需要设置为1。 ngram_token_size的值设置的越小,全文索引占用的空间也越小。一般来说,查询正好等于ngram_token_size的词,速度会更快,但是查询比它更长的词或短语,则会变慢。

N-gram分词处理

N-gram parser和系统默认的全文索引parser有如下不同点:

    词大小检查:因为有了ngram_token_size,所以innodb_ft_min_token_size和innodb_ft_max_token_size将不适用于n-gram。

    无用词(stopword)处理:通常,对于一个新的词,我们会查找stopwords表,看是否有匹配的词。如果有,这个词就不会加入到全文索引中。但是在n-gram中,我们会查找stopwords表,看是否包含里面的词。这样处理的原因是,在中日韩的文本中,有很多没有意义的字符,词语和标点符号。比如,如果我们把‘的’加入到stopwords表中,那么对于句子‘信息的系统’,在默认情况下我们分词结果为‘信息’,‘系统’。其中‘息的’和‘的系’被过滤掉了。

我们可以通过查询INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE和INFORMATION_SCHEMA.INNODB_FT_TABLE_TABLE来查询哪些词在全文索引里面。这是一个非常有用的调试工具。如果我们发现一个包含某个词的文档,没有如我们所期望的那样出现在查询结果中,那么这个词可能是因为某些原因不在全文索引里面。比如,它含有stopword,或者它的大小小于ngram_token_size等等。这个时候我们就可以通过查询这两个表来确认。下面是一个简单的例子:

简单的调试示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> INSERT INTO articles (title) VALUES ('信息系统');
Query OK, 1 row affected (0.01 sec)

mysql> SET GLOBAL innodb_ft_aux_table="test/articles";
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
+--------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+--------+--------------+-------------+-----------+--------+----------+
| 信息 | 1 | 1 | 1 | 1 | 0 |
| 息系 | 1 | 1 | 1 | 1 | 3 |
| 系统 | 1 | 1 | 1 | 1 | 6 |
+--------+--------------+-------------+-----------+--------+----------+
3 rows in set (0.00 sec)

 N-gram查询处理

文本查询(Text Searches)

  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素