本文档介绍如何在PolarDB MySQL版的列存索引(IMCI)上构建和使用全文索引,通过列级 COMMENT 配置倒排索引,即可利用MATCH...AGAINST语法或自动优化的LIKE查询实现毫秒级模糊检索。该功能基于 IMCI 的倒排索引与词项匹配机制实现,详细原理请参见列存索引全文检索能力剖析。
适用范围
您的集群版本需满足以下条件:
MySQL 8.0.1,且内核小版本需为8.0.1.1.52及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.32及以上版本。
语法说明
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 字段中提取内容建立索引。whole
5
不进行切分,将整个列作为词项,主要用于等值(如=或in等)加速。
mysql ngram
6
兼容 MySQL 的 ngram 分词器。
说明当前参数仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
配置参数(
KEY-VALUE)说明:参数名 (KEY)
默认值
取值说明
适用分词器类型(
type)enable
1
1:创建倒排索引(默认)0:删除倒排索引
所有
type
0
指定分词器类型(见上表)
所有
len
-
ngram分词器的分词长度,取值范围[1, 256)type=1(ngram)、type=6(mysql ngram)mode
0
分词器模式:
jieba (
type=2):0:精准模式(默认)1:全模式2:搜索引擎模式
ik (
type=3):0:智能模式(默认)1:最细粒度模式
json (
type=4):0:旧版本数组模式(默认)1:数组模式2:键值模式,如"*.id"、"[*].id"等
type=2, 3, 4score
0
是否支持排序:
0:禁止生成词频(TF)、文档频率(DF)等,忽略排序(默认)1:开启,支持MATCH ... AGAINST的相关性评分排序
说明当前参数仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
所有
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:支持
说明当前参数仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
所有
case_sensitive
0
是否大小写敏感:
0:大小写不敏感(默认)1:大小写敏感2:根据列的collate来决定(兼容 MySQL 模式)3:根据列的collate来决定(完全由collate决定)
所有
phrase
0
是否支持记录位置信息用于短语查询:
0:不记录位置信息(默认)1:记录位置信息
说明当前参数仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
所有
synonym
0
是否支持同义词:
0:不支持(默认)1:支持,查询模式2:支持,索引模式(需要重建倒排索引)
说明当前参数仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
所有
使用示例
一:创建全文索引
为需要进行文本检索的列创建全文索引,并根据业务需求选择分词器。
创建测试表:创建一个包含列存索引的表。
CREATE TABLE t1 ( id INT PRIMARY KEY, title VARCHAR(32) COMMENT "imci_fts(type=2)" )CHARSET utf8mb4 COMMENT 'columnar=1';(可选)修改全文索引:通过
ALTER TABLE语句将title列添加全文索引,并指定使用jieba分词器的搜索引擎模式。ALTER TABLE t1 MODIFY title VARCHAR(32) COMMENT "imci_fts(type=2,mode=0)";(可选)验证分词效果:在选择分词器前,可使用
dbms_imci.fts_tokenize函数预览不同分词器对文本的处理效果。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 语句执行文本查询。
使用
MATCH...AGAINST查询:-- 插入示例数据 INSERT INTO t1 VALUES (16, 'polarDB全文索引功能title'), (17, '数据库title性能优化'); -- 查询 title 列包含“索引”的记录 SELECT * FROM t1 WHERE MATCH(title) AGAINST("title");通过
EXPLAIN查看执行计划,可以看到FtsTableScan算子,表示查询已命中全文索引。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补充扫描,保证结果完整性。加速
LIKE查询:为兼容已有业务代码,IMCI 支持将特定的LIKE查询自动转换为MATCH...AGAINST以进行加速。SET imci_convert_like_to_match = on; 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查询已被成功加速。match转为like:在缺少全文索引,为确保查询仍能正确执行,同时尽可能利用已有索引时,IMCI可能会将MATCH转换为LIKE,执行计划显示为全表扫描。SET imci_enable_query_fts_like = on; 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%") | +----+----------------------+------+-----------------------------------------------------------------+
三:管理与监控索引
查询索引的构建状态、元数据信息,并在不再需要时删除索引。
监控索引构建进度和状态:
-- 查看所有倒排索引 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]';删除全文索引:如果不再需要某个列的全文索引,可以通过修改列的
COMMENT将其删除。ALTER TABLE t1 MODIFY title VARCHAR(255) COMMENT 'imci_fts(enable=0)';
四:核心配置参数说明
参数名 | 级别 | 说明 |
imci_enable_fts | Global | 是否允许在列存节点上创建倒排索引。
|
imci_enable_fts_query | Global / Session | 是否允许在列存节点上使用倒排索引。
|
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 | 是否开启倒排索引预过滤优化。
|
imci_convert_like_to_match | Global / Session | 是否开启将
|
imci_enable_query_fts_like | Global / Session | 是否开启将
|
imci_enable_match_expr_fallback | Global / Session | 是否开启倒排索引的尚未构建增量数据查询。
|
imci_fts_build_fts_cnt | Global | 倒排索引构建的并发数。 取值范围:0-512,默认值:4。 说明 当前参数仅适用于以下版本:
|
imci_fts_user_dict_table | Global | 配置全文索引的自定义词典,格式:库名/表名。 说明 当前参数仅适用于以下版本:
|
imci_fts_user_dict_update | Global | 是否重新加载
说明 当前参数仅适用于以下版本:
|
imci_convert_json_overlap_to_match | Global/Session | 控制是否开启
|
imci_convert_json_contains_to_match | Global/Session | 控制是否开启
|
imci_convert_json_extract_to_match | Global/Session | 控制是否开启
|
imci_convert_equal_to_match | Global/Session | 控制是否开启
|
imci_convert_in_to_match | Global/Session | 控制是否开启
|
imci_convert_ne_to_match | Global/Session | 控制是否开启
|
imci_enable_fts_synonym | Global / Session | 是否支持同义词。
说明 当前参数仅适用于以下版本:
|
imci_enable_fts_parse_term_with_and | Global / Session | 是否支持查询字符串分词后用
|
imci_enable_fts_parse_term_with_phrase | Global / Session | 是否支持
|
imci_fts_stop_word_table | Global | 配置全文索引的自定义停止词,格式: 说明 当前参数仅适用于以下版本:
|
imci_fts_stop_word_update | Global | 是否重新加载
说明 当前参数仅适用于以下版本:
|
imci_fts_synonym_table | Global | 配置全文索引的自定义同义词,格式: 说明 当前参数仅适用于以下版本:
|
imci_fts_synonym_update | Global | 是否重新加载
说明 当前参数仅适用于以下版本:
|
级别为 GLOBAL 的参数无法通过命令行直接修改,仅可通过控制台设置;在命令行中执行时,默认视为 SESSION 级别操作。
自定义词典
IMCI全文索引功能支持通过自定义表来实现自定义词典功能,以获取更贴近业务实际场景的分词结果。
创建自定义词典表
首先需要定义一个与my_fts_dict表结构相同的表,列名称需要和my_fts_dict表保持一致。
type:分词器类型,仅支持jieba分词器(类型为2)和 ik 分词器(类型为3)。
word:实体词。
is_added:从自定义词典中添加(值为1)或删除(值为2)。
CREATE TABLE my_fts_dict ( `type` INT UNSIGNED NOT NULL COMMENT '2 for jieba, 3 for ik', `word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'dict word', `is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 for add, 2 for delete' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts user dict';自定义词典本身是一张InnoDB表,读写操作与普通表一样。
添加词条:
INSERT INTO my_fts_dict VALUES(2, "PolarDB", 1)删除词条:
INSERT INTO my_fts_dict(type, word, is_added) VALUES(2, "PolarDB", 2); 或 DELETE FROM my_fts_dict WHERE type=2 AND word = "PolarDB";
配置自定义词典
创建自定义词典表后,可以配置
imci_fts_user_dict_table选项的值。例如,test/my_fts_dict'。SET GLOBAL imci_fts_user_dict_table = 'test/my_fts_dict';如果
imci_fts_user_dict_table已经设置,也可以通过imci_fts_user_dict_update配置为ON,来触发重新加载imci_fts_user_dict_table指定的自定义词典。SET GLOBAL imci_fts_user_dict_update = ON;说明新自定义词典只对后面新构建的倒排索引生效,若需要对已经构建好的倒排索引生效则需要重建倒排索引。
自定义同义词
IMCI 全文索引功能支持通过自定义表来实现自定义同义词功能。
自定义同义词功能仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
创建自定义同义词表
首先需要定义一个与 my_synonym_dict 表结构相同的表,列名称需要和 my_synonym_dict 表保持一致。
word:同义词列表,不同词由逗号隔开。type:同义词类型。0表示列表中所有词相互为同义词,如"db,database,polardb"表示"db" <=> "database" <=> "polardb",即查找"db"或"database"或"polardb"时均会输出所有匹配"db"、"database"与"polardb"的数据。1表示列表中第一个词而其它均为该词的同义词,如"db,database,polardb"表示"db" => "database", "polardb",即查找"db"时会输出所有匹配"db"、"database"与"polardb"的数据,但查找"database"时只会输出匹配"database"的数据。
CREATE TABLE my_synonym_dict (
`word` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'comma-separated synonyms',
`type` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 for equivalent, 1 for mapping'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts synonym';自定义词典本身是一张 InnoDB 表,读写操作与普通表一样。
添加词条:
INSERT INTO my_synonym_dict VALUES("db,database,polardb", 0); INSERT INTO my_synonym_dict VALUES("imci,clickhouse,duckdb", 1);删除词条:
DELETE FROM my_synonym_dict WHERE type=1 AND word = "imci,clickhouse,duckdb";
配置自定义同义词
创建自定义同义词表后,可以配置 imci_fts_synonym_table 选项的值。例如,test/my_synonym_dict,其中 test 为库名,my_synonym_dict 为表名。
SET GLOBAL imci_fts_synonym_table = 'test/my_synonym_dict';如果 imci_fts_synonym_table 已经设置,也可以通过 imci_fts_synonym_update 配置为 ON,来触发重新加载 imci_fts_synonym_table 指定的自定义同义词。
SET GLOBAL imci_fts_synonym_update = ON;若 synonym 为索引模式(如 COMMENT "imci_fts(type=0 synonym=1)"),更新同义词后只对倒排索引新增部分生效,若需要全部生效需要重建全文索引。
自定义停止词
IMCI 全文索引功能支持通过自定义表来实现自定义停止词功能。
自定义停止词功能仅适用于以下版本:
MySQL 8.0.1,且内核小版本需为8.0.1.1.57及以上版本。
MySQL 8.0.2,且内核小版本需为8.0.2.2.37及以上版本。
创建自定义停止词表
首先需要定义一个与 my_stop_words 表结构相同的表,列名称需要和 my_stop_words 保持一致。
word:停止词。is_added:从自定义词典中添加(值为 1)或删除(值为 0)。
CREATE TABLE my_stop_words (
`word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'stop word',
`is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 for add, 0 for delete'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts stop word';自定义词典本身是一张 InnoDB 表,读写操作与普通表一样。
添加词条:
INSERT INTO my_stop_words VALUES("am", 1); INSERT INTO my_stop_words VALUES("chinese", 1);删除词条:
INSERT INTO my_stop_words(word, is_added) VALUES("chinese", 0); -- 或 DELETE FROM my_stop_words WHERE is_added=1 AND word = "chinese";
配置自定义停止词
创建自定义停止词表后,可以配置 imci_fts_stop_word_table 选项的值。例如,test/my_stop_words,其中 test 为库名,my_stop_words 为表名。
SET GLOBAL imci_fts_stop_word_table = 'test/my_stop_words';如果 imci_fts_stop_word_table 已经设置,也可以通过 imci_fts_stop_word_update 配置为 ON,来触发重新加载 imci_fts_stop_word_table 指定的自定义停止词。
SET GLOBAL imci_fts_stop_word_update = ON;新自定义词典只对后面新构建的倒排索引生效,若需要对已经构建好的倒排索引生效则需要重建倒排索引。
常见问题
Q1:如何选择合适的分词器?
英文或格式化文本:使用默认的
type=0(token),按空格和标点符号分词。中文精确搜索:使用
type=2(jieba) 或type=3(ik) 的默认模式。JSON 内容检索:使用
type=4(json) 并配合expr参数指定要索引的 JSON 路径。可以通过dbms_imci.fts_tokenize函数预览不同分词器对文本的处理效果。
Q2:为什么我的查询没有使用全文索引?
请确认
SET imci_enable_fts_query = ON;已执行。这是最常见的原因。检查
EXPLAIN的输出,确认是否有FtsTableScan算子。如果没有,可能是查询模式不匹配或系统评估后认为全表扫描成本更低。
Q3: LIKE查询和MATCH...AGAINST有何区别?
LIKE '%keyword%'在没有全文索引时会导致全表扫描,性能极差。即使被 IMCI 加速,其功能也相对单一。MATCH...AGAINST是专为全文检索设计的语法,不仅性能高,未来还支持更复杂的布尔查询、相关性排序等高级功能。建议新开发业务优先使用MATCH...AGAINST。