- 当一个全文索引被创建时,必须有一个列与word进行映射,InnoDB 会隐式的建立一个名为 FTS_DOC_ID 的列(bigint unsigned not null),并在其上创建一个唯一索引,用于标识分词出现的记录行。一系列的辅助表会被同时创建,用于存储倒排索引的信息。
示例
SELECT table_id, name, space
FROM
INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE
name LIKE
'test/%';
运行结果如下:
+-----------+--------------------------------------------------------------------------+-------+
| table_id | name | space
|
+-----------+--------------------------------------------------------------------------+-------+
| 333 |
test/FTS_0000000000000147_00000000000001c9_INDEX_1 | 289 |
| 334 |
test/FTS_0000000000000147_00000000000001c9_INDEX_2 | 290 |
| 335 |
test/FTS_0000000000000147_00000000000001c9_INDEX_3 | 291 |
| 336 |
test/FTS_0000000000000147_00000000000001c9_INDEX_4 | 292 |
| 337 |
test/FTS_0000000000000147_00000000000001c9_INDEX_5 | 293 |
| 338 |
test/FTS_0000000000000147_00000000000001c9_INDEX_6 | 294 |
| 330 |
test/FTS_0000000000000147_BEING_DELETED | 286 |
| 331 |
test/FTS_0000000000000147_BEING_DELETED_CACHE | 287 |
| 332 |
test/FTS_0000000000000147_CONFIG | 288 |
| 328 | test/FTS_0000000000000147_DELETED | 284 |
| 329 |
test/FTS_0000000000000147_DELETED_CACHE | 285
|
| 327 |
test/opening_lines
| 283
|
+-----------+--------------------------------------------------------------------------+-------+
列名 |
解释 |
FTS_0000000000000147_00000000000001c9_INDEX_1-6 |
这 6 张辅助表用于存储倒排索引,存储的是分词、文档ID和位置;即 InnoDB 采用的是 full inverted index。 |
FTS_0000000000000147_DELETED |
存储的是已经被删除的、但还未从全文索引数据中移除的文档 |
FTS_0000000000000147_DELETED_CACHE |
FTS_0000000000000147_DELETED 的缓存表。 |
FTS_0000000000000147_BEING_DELETED |
存储的是已经被删除的、且正在从全文索引数据中移除的文档 (即删除 FTS Index Cache 并做了 OPTIMIZE TABLE)
主要用于辅助进行 OPTIMIZE TABLE 时将 DELETED/DELETED_CACHED 表中的记录转储到其中 |
FTS_0000000000000147_BEING_DELETED_CACHE |
FTS_0000000000000147_BEING_DELETED 的缓存表。 |
FTS_0000000000000147_CONFIG |
存储全文索引的内部信息;最重要的是存储FTS_SYNCED_DOC_ID,表示已经解析且刷盘的文档;当发生 crash recovery 时,可以通过 FTS_SYNCED_DOC_ID 去判断哪些文档没有刷盘、需要重新解析并加入到全文索引缓存中。 |
数据插入
- 如果当插入一个文档时,就需要进行分词、更新辅助表等操作,那可能会造成极大的开销。
- 为了避免这个问题,InnoDB 引入了全文索引缓存,用于缓存最近插入的数据,直到缓存占满才会批量将数据刷盘写入辅助表;
- 可以通过 INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE 查询最近插入的数据,innodb_ft_cache_size / innodb_ft_total_cache_size 参数控制单个表/所有表的全文索引缓存大小
注
全文索引缓存只缓存了最近插入的数据,而没有缓存辅助表的数据,当返回结果时,需要将辅助表的数据和缓存中最近插入的数据进行合并后再返回。
数据删除
- 如果删除一个文档时,就需要更新辅助表,这也可能会造成极大的开销。为了避免这个问题,InnoDB会记录其FTS Document ID,并将其保存在 FTS_0000000000000147_DELETED/FTS_0000000000000147_DELETED_CACHE 表,而不会将其从辅助表中删除,如果要彻底清理被删除数据,需要通过optimize table重建全文索引。
示例
SET GLOBAL
innodb_optimize_fulltext_only=ON;
Query OK, 0 rows affected (0.01 sec)
OPTIMIZE TABLE opening_lines;
运行结果如下:
+----------------------+------------+------------+------------+
| Table | Op | Msg_type | Msg_text
|
+----------------------+------------+------------+------------+
| test.opening_lines | optimize |
status | OK |
+----------------------+------------+------------+------------+
1 row in set (0.01 sec)
数据更新
- 对于数据更新,InnoDB的处理方式是先删除数据、然后插入数据。
监控表
- 在 InnoDB 全文索引中辅助表不能被直接查询,只能通过查询 information_schema 下封装过的临时表来监控全文索引状态,具体如下:
INNODB_FT_CONFIG
INNODB_FT_INDEX_TABLE
INNODB_FT_INDEX_CACHE
INNODB_FT_DEFAULT_STOPWORD
INNODB_FT_DELETED
INNODB_FT_BEING_DELETED