暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PolarDB · InnoDB 全文索引简介(一)

Z 2023-06-25
419

前言

从MySQL5.6版本开始支持InnoDB引擎的全文索引,语法层面上大多数兼容之前MyISAM的全文索引模式。所谓全文索引,是一种通过建立倒排索引,快速匹配文档的方式。MySQL支持三种模式的全文检索模式:

  1. 自然语言模式(IN NATURAL LANGUAGE MODE),即通过MATCH AGAINST 传递某个特定的字符串来进行检索。
  2. 布尔模式(IN BOOLEAN MODE),可以为检索的字符串增加操作符,例如“+”表示必须包含,“-”表示不包含,“*”表示通配符(这种情况, 即使传递的字符串较小或出现在停词中,也不会被过滤掉),其他还有很多特殊的布尔操作符,可以通过如下参数控制:

     mysql> show variables like '%ft_boolean_syntax%';
     +-------------------+----------------+
     | Variable_name     | Value          |
     +-------------------+----------------+
     | ft_boolean_syntax | + -><()~*:""&| |
     +-------------------+----------------+
     1 row in set (0.00 sec)
    
    复制
  3. 查询扩展模式(WITH QUERY EXPANSION), 这种模式是自然语言模式下的一个变种,会执行两次检索,第一次使用给定的短语进行检索,第二次是结合第一次相关性比较高的行进行检索。

目前MySQL支持在CHAR、VARCHAR、TEXT类型的列上定义全文索引。

本文只是简单的分析了全文索引涉及到的代码模块以及5.7的一些新特性,源码部分基于MySQL5.7.8-rc版本,更细节的部分并未深入。

创建全文索引

如下例所示,一个简单的创建带全文索引表的SQL:

create table t1 (a int auto_increment primary key, b text, fulltext(b));
复制

磁盘上会产生多个文件:

$ls -lh /u01/my57/data/test/
total 1.3M

 FTS_000000000000010b_0000000000000154_INDEX_1.ibd
 FTS_000000000000010b_0000000000000154_INDEX_2.ibd
 FTS_000000000000010b_0000000000000154_INDEX_3.ibd
 FTS_000000000000010b_0000000000000154_INDEX_4.ibd
 FTS_000000000000010b_0000000000000154_INDEX_5.ibd
 FTS_000000000000010b_0000000000000154_INDEX_6.ibd
 FTS_000000000000010b_BEING_DELETED_CACHE.ibd
 FTS_000000000000010b_BEING_DELETED.ibd
 FTS_000000000000010b_CONFIG.ibd
 FTS_000000000000010b_DELETED_CACHE.ibd
 FTS_000000000000010b_DELETED.ibd
 t1.frm
 t1.ibd
复制

除了t1.frm和t1.ibd外,共分为以下几类表

  1. FTS_000000000000010b_0000000000000154_INDEX_1~6.ibd这6个文件用于存储倒排索引,存储的是分词和位置以及document ID,根据分词的第一个字符值进行分区,映射到不同的文件中; 文件的命名规则为FTS_{TABLE_ID}_{INDEX_ID}_INDEX_{N}.ibd

  2. FTS_000000000000010b_DELETED.ibd 包含已经被删除的DOC_ID,但还没从全文索引数据中删掉; FTS_000000000000010b_DELETED_CACHE.ibd 是前者的内存缓存(但是搜索了下代码,只有当fts_cache_t::deleted_doc_ids被使用时,才会在sync时转储到该表中,但并没有发现任何地方使用这个对象)

  3. FTS_000000000000010b_BEING_DELETED_CACHE.ibd 和 FTS_000000000000010b_BEING_DELETED.ibd,包含了已经被删除索引记录并且正在从全文索引中移除的DOC ID,前者是后者的内存版本,这两个表主要用于辅助进行OPTIMIZE TABLE时将DELETED/DELETED_CACHED表中的记录转储到其中。

  4. FTS_000000000000010b_CONFIG.ibd,包含全文索引的内部信息,最重要的存储是FTS_SYNCED_DOC_ID,表示已经解析并刷到磁盘的doc id, 在崩溃恢复时,可以根据这个值判断哪些该重新解析并加入到索引cache中。

建全文索引辅助表函数参考:

ha_innobase::create
     |--> create_table_info_t::create_table
            |--> fts_create_common_tables
复制

当对一个已经存在的表上创建全文索引时,InnoDB采用了fork多个线程进行并发构建全文索引项的方法,并发度由参数 innodb_ft_sort_pll_degree 控制。因此在restore一个全文索引表时,我们建议先建表、导入数据,再在表上创建全文索引。

参考函数:row_merge_read_clustered_index --> row_fts_start_psort 线程回调函数为fts_parallel_tokenization

当表上存在全文索引时,就会隐式的建立一个名为FTS_DOC_ID的列,并在其上创建一个唯一索引,用于标识分词出现的记录行。你也可以显式的创建一个名为FTS_DOC_ID的列,但需要和隐式创建的列类型保持一致。

为了维护表上的全文索引信息,全文索引模块定义了大量的类来进行管理,总的来说如下图所示:

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论