mysql全文检索怎么做 mysql全文索引查询

MySQL的全文索引Fulltext Index | 包括ngram InnoDB的全文索引使用反向索引的设计 。反向索引存储了一个单词(word)列表,对于每个单词,都有一个文档的列表,来标识这个单词出现的地方 。为了支持临近搜索(proximity search),每个单词的位置信息也以字节偏移的方式存储 。
当创建了InnoDB全文索引,一系列的索引表会一同被创建 , 见下面的例子:
最前面的六个表包含了反向索引 , 它们被称作附属索引表(auxiliary index table) 。当输入的表被索引(tokenized)后 , 每个独立的单词(亦称作“tokens”)会被携带其DOC_ID和位置信息插入到索引表中 。根据单词第一个字符的字符集排序权重,在六个索引表中对单词进行完全排序和分区 。
反向索引分区到六个附属索引表以支持并行的索引创建 。默认有2个线程复制索引(Tokenize)、排序、插入单词和关联数据到索引表中 。工作的线程的数量由innodb_ft_sort_pll_degree 配置项控制的 。对于大表的全文索引,可以考虑增加线程数量 。
如果主表创建在 xx表空间 , 索引表存储在它们自己的表空间中 。反之,索引表存储于其索引的表空间中 。
前面例子展示的另外一种索引表被称作通用索引表,它们被用于全文索引的“删除处理(deletion handing)”和存储内部状态 。不同于为每个全文索引都各自创建的反向索引表,这组表对特定表的所有全文索引都是共用的 。
即使全文索引删掉了 , 通用索引(Common Index)也会被保留,当全文索引删除后,为这个索引而创建的FTS_DOC_ID列依然保留,因为移除FTS_DOC_ID列会导致重构之前被索引的表 。管理FTS_DOC_ID列需要用到通用索引表 。
为了防止大量并发读写附属表,InnoDB使用全文索引缓存去临时缓存最近的插入行 。在存满并刷入磁盘之前 , 缓存的内容一直存储在内存之中,可以通过查询 INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE 表去查看最近缓存的插入行 。
缓存和批处理刷新行为避免了对辅助索引表的频繁更新,频繁更新可能会在繁忙的插入和更新期间导致并发访问问题 。批处理还避免了对同一个word的多次插入 , 最大化的减少了重复的条目 。相同的word会先merge再刷入到磁盘中,而不是为每个word单独插入,这样提高了插入效率并且使得索引附属表尽可能的小 。
全文索引缓存只缓存最近插入的行,查询时,已经刷入磁盘(附属索引表)的数据不会再回到索引缓存中 。附属索引表中的内容是直接查询的,最终返回的结果返回前需要将附属索引表的结果和索引缓存中的结果合并 。
InnoDB使用被称作DOC_ID的唯一文件描述符,将全文索引中的单词与该单词在文档中的记录映射起来 。映射关系需要索引表中的 FTS_DOC_ID 列 。在创建全文索引时 , 如果没有定义 FTS_DOC_ID 列 , InnoDB会自动的加入一个隐藏的 FTS_DOC_ID 列 。下面是一个例子,
CREATE FULLTEXT INDEX ft_index ON xxxxxxxx(CONTEXT)
[2021-11-12 18:14:04] [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID
重点看一下这一行: [HY000][124] InnoDB rebuilding table to add column FTS_DOC_ID ,InnoDB重新构建了这个表,并且添加了一个列 FTS_DOC_ID。
在CREATE TABLE的过程中添加 FTS_DOC_ID 的时间成本要低于在已经有数据的表上建立全文索引 。如果在表加载数据之前定义 FTS_DOC_ID 列,这个表和它的索引都不需要为了新增列而重新构建 。如果你不需要考虑 CREATE FULLTEXT INDEX 的性能,可以让InnoDB为你创建 FTS_DOC_ID 列 。InnoDB会新增一个隐藏的 FTS_DOC_ID 列,并且在 FTS_DOC_ID 上建立唯一索引(FTS_DOC_ID_INDEX) 。如果你想自行创建 FTS_DOC_ID 列,这个列必须定义为 BIGINT UNSIGNED NOT NULL 且命名为FTS_DOC_ID(全大写),如下例子:

推荐阅读