IMCI全文索引使用说明

本文档介绍如何在PolarDB MySQL版的列存索引(IMCI)上构建和使用全文索引,通过列级 COMMENT 配置倒排索引,即可利用MATCH...AGAINST语法或自动优化的LIKE查询实现毫秒级模糊检索。该功能基于 IMCI 的倒排索引与词项匹配机制实现,详细原理请参见列存索引全文检索能力剖析

说明

该功能目前处于灰度试用阶段,请通过提交工单进行申请试用。

语法说明

PolarDB IMCI 可以在创建表时指定列comment或通过DDL修改列comment来创建或修改或删除倒排索引。

语法格式

  • 创建表时定义全文索引:

    CREATE TABLE table_name (
        column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])"
    ) COMMENT 'columnar=1';
  • 使用ALTER修改列以添加/修改索引:

    ALTER TABLE table_name MODIFY column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])";
    重要

    修改COMMENT可能会触发倒排索引的重建,大表操作建议在业务低峰期执行。

  • 使用ALTER修改列以删除索引:

    ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'imci_fts(enable=0)';

参数说明:

需在表级COMMENT中设置'columnar=1'以创建 IMCI 列存表,全文索引通过列的COMMENT配置,格式为imci_fts(TYPE=VALUE[, KEY=VALUE]...),其中TYPE为必填,KEY为可选,多个KEY用英文逗号分隔。

  • 分词器类型(type 参数):

    分词器

    type 值

    说明

    token

    0 (默认)

    按空格、标点等非字母数字字符进行分词,适用于英文或格式化文本。

    ngram

    1

    按固定长度切分字符(由 len 参数控制),适用于任意语言的模糊匹配。

    jieba

    2

    基于词库的中文分词器,适用于中文语义化搜索。

    ik

    3

    另一款常用的中文分词器。

    json

    4

    通过 JSONPath 表达式(需配合 expr 参数)从 JSON 字段中提取内容建立索引。

  • 配置参数(KEY-VALUE)说明:

    参数名 (KEY)

    默认值

    取值说明

    适用分词器类型(type

    enable

    1

    • 1: 创建倒排索引(默认)

    • 0: 删除倒排索引

    所有

    type

    0

    指定分词器类型(见上表)

    所有

    len

    -

    ngram 分词器的分词长度,取值范围 [2, 256)

    type=1 (ngram)

    mode

    0

    分词器模式:

    • jieba (type=2):

      • 0: 精准模式(默认)

      • 1: 全模式

      • 2: 搜索引擎模式

    • ik (type=3):

      • 0: 智能模式(默认)

      • 1: 最细粒度模式

    • json (type=4):
      0: 数组模式(默认)

    type=2, 3, 4

    score

    0

    是否支持排序:

    • 0: 禁止生成词频(TF)、文档频率(DF)等,忽略排序(默认)

    • 1: 开启,支持 MATCH ... AGAINST 的相关性评分排序

    所有

    seg_size

    0

    指定倒排索引段大小:

    • 0: 使用系统变量 imci_fts_build_segment_size 的值

    • 其他值:指定具体段大小

    所有

    pack_cnt_min

    0

    倒排索引构建的数据单元最小数目:

    • 0: 使用系统变量 imci_fts_build_packcnt_min 的值

    • 其他值:指定具体段大小

    所有

    pack_cnt_max

    0

    倒排索引构建的数据单元最大数目:

    • 0: 使用系统变量 imci_fts_build_packcnt_max 的值

    • 其他值:指定具体段大小

    所有

    stop_word

    0

    是否支持停用词:

    • 0: 不支持(默认)

    • 1: 支持

    所有

    case_sensitive

    0

    是否大小写敏感:

    • 0: 大小写不敏感(默认)

    • 1: 大小写敏感

    所有

使用示例

一:创建全文索引

为需要进行文本检索的列创建全文索引,并根据业务需求选择分词器。

  1. 创建测试表
    创建一个包含列存索引的表。

    CREATE TABLE t1 (
        id INT PRIMARY KEY,
        title VARCHAR(32) COMMENT "imci_fts(type=2)"
    )CHARSET utf8mb4 COMMENT 'columnar=1';
  2. (可选)修改全文索引
    通过ALTER TABLE语句将title列添加全文索引,并指定使用 jieba 分词器的搜索引擎模式。

    ALTER TABLE t1 MODIFY title VARCHAR(32) COMMENT "imci_fts(type=2,mode=0)";
  3. (可选)验证分词效果
    在选择分词器前,可使用 dbms_imci.fts_tokenize 函数预览不同分词器对文本的处理效果。

    -- 英文文本,默认 token 分词
    CALL dbms_imci.fts_tokenize("I am Chinese");
    -- 结果:["I", "am", "Chinese"]
    
    -- 英文文本,使用 jieba 分词
    CALL dbms_imci.fts_tokenize("I am Chinese", "type=2");
    -- 结果:["Chinese"] (仅识别中文词汇)
    
    -- 中文文本,ngram 分词(长度2)
    CALL dbms_imci.fts_tokenize("我是中国人", "type=1");
    -- 结果:["我是", "是中", "中国", "国人"]
    
    -- 中文文本,jieba 全模式
    CALL dbms_imci.fts_tokenize("我是中国人", "type=2,mode=1");
    -- 结果:["中国", "国人"] 
    CALL dbms_imci.fts_tokenize("I am PolarDB");
    -- 结果:["i", "am", "polardb"]  
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=1");
    -- 结果:["i ", " a", "am", "m ", " p", "po", "ol", "ar", "rd", "db"]
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2");
    -- 结果:["PolarDB"]
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2,mode=1");
    -- 结果: ["polardb"]

二:执行全文检索查询

索引创建后,IMCI 会在后台完成构建。构建完成后,即可通过 MATCH...AGAINST 或优化的 LIKE 语句执行文本查询。

  1. 使用MATCH...AGAINST查询:

    -- 插入示例数据
    INSERT INTO t1 VALUES 
    (16, 'polarDB全文索引功能title'), 
    (17, '数据库title性能优化');
    -- 查询 title 列包含“索引”的记录
    SELECT * FROM t1 WHERE MATCH(title) AGAINST("title");

    通过EXPLAIN查看执行计划,可以看到 FtsTableScan 算子,表示查询已命中全文索引。

    mysql> explain SELECT * FROM t1 WHERE MATCH(title) AGAINST("title") AND id > 10;
    +----+------------------------+------+-----------------------------------------------------------------+
    | ID | Operator               | Name | Extra Info                                                      |
    +----+------------------------+------+-----------------------------------------------------------------+
    |  1 | Select Statement       |      | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) |
    |  2 | └─Compute Scalar       |      |                                                                 |
    |  3 |   └─FILTER             |      | Cond: (t1.id > 10)                                              |
    |  4 |     └─FtsTableScan     | t1   | Term: ("title") Fallback: (t1.title LIKE "%title%")             |
    +----+------------------------+------+-----------------------------------------------------------------+

    Fallback表示对于尚未被索引的增量数据,系统会自动使用LIKE补充扫描,保证结果完整性。

  2. 加速LIKE查询:
    为兼容已有业务代码,IMCI 支持将特定的LIKE查询自动转换为 MATCH...AGAINST 以进行加速。

    mysql> SET imci_convert_like_to_match = on;
    mysql> explain SELECT * FROM t1 WHERE title  LIKE "%title%";
    +----+------------------------+------+-----------------------------------------------------------------+
    | ID | Operator               | Name | Extra Info                                                      |
    +----+------------------------+------+-----------------------------------------------------------------+
    |  1 | Select Statement       |      | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) |
    |  2 | └─Compute Scalar       |      |                                                                 |
    |  3 |   └─FILTER             |      | Cond: (t1.title LIKE "%title%")                                 |
    |  4 |     └─FtsTableScan     | t1   | Term: ("title") Fallback: (t1.title LIKE "%title%")             |
    +----+------------------------+------+-----------------------------------------------------------------+

    执行计划同样会显示 FtsTableScan 算子,证明 LIKE 查询已被成功加速。

  3. match转为like

    在缺少全文索引,为确保查询仍能正确执行,同时尽可能利用已有索引时,IMCI可能会将MATCH转换为LIKE,执行计划显示为全表扫描。

    mysql> SET imci_enable_query_fts_like = on;
    mysql> explain SELECT * FROM t1 WHERE MATCH(title) AGAINST("title");
    +----+----------------------+------+-----------------------------------------------------------------+
    | ID | Operator             | Name | Extra Info                                                      |
    +----+----------------------+------+-----------------------------------------------------------------+
    |  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) |
    |  2 | └─Compute Scalar     |      |                                                                 |
    |  3 |   └─Table Scan       | t1   | Cond: (title LIKE "%title%")                                    |
    +----+----------------------+------+-----------------------------------------------------------------+

三:管理与监控索引

查询索引的构建状态、元数据信息,并在不再需要时删除索引。

  1. 监控索引构建进度和状态:

    -- 查看所有倒排索引
    SHOW imci indexes fulltext;
    SELECT * FROM information_schema.imci_fts_indexes;
    
    -- 查看指定倒排索引
    SHOW imci indexes fulltext FOR [db_name].[table_name];
    SELECT * FROM information_schema.imci_fts_indexes 
    WHERE schema_name='[db_name]' AND table_name='[table_name]';
    
    -- 查看指定倒排索引的元数据
    SELECT * FROM information_schema.imci_fts_index_metas 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
    
    -- 查看指定倒排索引的段数据
    SELECT * FROM information_schema.imci_fts_index_segs 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
    
    -- 查看指定倒排索引的列存数据
    SELECT * FROM information_schema.imci_fts_index_packs 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
  2. 删除全文索引:
    如果不再需要某个列的全文索引,可以通过修改列的COMMENT将其删除。

    ALTER TABLE t1 MODIFY title VARCHAR(255) COMMENT 'imci_fts(enable=0)';

四:核心配置参数说明

参数名

级别

说明

imci_enable_fts

Global

是否允许在列存节点上创建倒排索引。

  • ON(默认):开启,支持字符串与JSON等类型。

  • OFF:关闭。

imci_enable_fts_query

Global/

Session

是否允许在列存节点上使用倒排索引。

  • ON:开启。

  • OFF(默认):关闭。

imci_fts_build_pack_cnt_min

Global

倒排索引构建时控制每一倒排索引的列存数据块最小数目。

取值范围为:0-8192,默认值为8,其中0表示暂时不构建。

imci_fts_build_pack_cnt_max

Global

倒排索引构建时控制每一倒排索引的列存数据块最大数目。

取值范围为:0-8192,默认值为128。

imci_fts_build_segment_size

Global

倒排索引构建时控制每一倒排索引的段大小。

取值范围为:0-4294967295,默认值为536870912(512MB),单位字节。

imci_fts_lru_cache_capacity

Global

倒排索引字典缓存空间。

取值范围:[DBNodeClassMemory*1/10~DBNodeClassMemory*1/2],默认值为[DBNodeClassMemory*10/100]。

imci_enable_fts_pruner

Global/

Session

是否开启倒排索引预过滤优化。

  • ON(默认):开启。

  • OFF:关闭。

imci_convert_like_to_match

Global/

Session

是否开启将like转换为match并利用倒排索引进行加速。

  • "ON":开启。

  • "OFF"(默认):关闭。

  • "ONLY_MATCH":开启且忽略like表达式;

imci_enable_query_fts_like

Global/

Session

是否开启将match转换为like

  • ON:开启。

  • OFF(默认):关闭。

imci_enable_match_expr_fallback

Global/

Session

当倒排索引不可用或正在构建时,是否允许查询降级执行。

  • ON(默认):开启。

  • OFF:关闭。

重要

级别为 GLOBAL 的参数无法通过命令行直接修改,仅可通过控制台设置;在命令行中执行时,默认视为 SESSION 级别操作。

常见问题

Q1: 如何选择合适的分词器?

  • 英文或格式化文本:使用默认的type=0(token),按空格和标点符号分词。

  • 中文精确搜索:使用type=2(jieba) 或type=3(ik) 的默认模式。

  • JSON 内容检索:使用 type=4 (json) 并配合 expr 参数指定要索引的 JSON 路径。

  • 可以通过dbms_imci.fts_tokenize函数预览不同分词器对文本的处理效果。

Q2: 为什么我的查询没有使用全文索引?

  1. 请确认 SET imci_enable_fts_query = ON; 已执行。这是最常见的原因。

  2. 检查EXPLAIN的输出,确认是否有FtsTableScan算子。如果没有,可能是查询模式不匹配或系统评估后认为全表扫描成本更低。

Q3: LIKE查询和MATCH...AGAINST有何区别?

  • LIKE '%keyword%' 在没有全文索引时会导致全表扫描,性能极差。即使被 IMCI 加速,其功能也相对单一。

  • MATCH...AGAINST是专为全文检索设计的语法,不仅性能高,未来还支持更复杂的布尔查询、相关性排序等高级功能。建议新开发业务优先使用MATCH...AGAINST