基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
全文搜索
更新时间:2026-09-16 17:42:25
OceanBase AI 数据库通过全文索引功能提供了对文本数据的高效搜索能力。
适用场景
在涉及大量文本数据需要进行模糊搜索的场景,如果通过全表扫描来对每一行数据进行模糊查询,文本较大、数据量较多的情况下性能往往不能满足要求。另外一些复杂的查询场景,如近似匹配、相关性排序等,也难以通过改写 SQL 支撑。
全文索引可以更好的支撑这些场景,通过预先处理文本内容,建立关键词索引,全文索引可以有效提升全文搜索效率。全文索引适用于多种场景,下面列举几个具体的案例:
企业内部知识库:许多大型企业都会构建自己的内部知识库系统,用来存储项目文档、会议记录、研究报告等资料。使用全文索引可以帮助员工更加快速准确地找到所需信息,提高工作效率。
在线图书馆与电子书平台:对于提供大量书籍资源供用户阅读的服务来说,全文索引是极其重要的。用户可以输入书名、作者名字甚至是书中某段文字作为关键字来进行搜索,系统基于全文索引迅速定位到符合条件的结果。
新闻门户和社交媒体网站:这类平台上每天都会产生海量的新鲜内容,包括文章、帖子、评论等。利用全文索引可以让用户按照自己关心的话题、事件或是人物名称来过滤信息流,获取最相关的内容。
法律文书搜索系统:法律行业涉及到大量的文件审阅工作,如合同、判决书、法律法规条文等。一个高效的全文搜索引擎能够极大地简化律师的工作流程,让他们能够更快地找到先例、引用条款以及相关的法律依据。
医疗健康信息系统:在医疗领域,医生经常需要查阅病人的历史病例、最新的医学研究论文以及其他参考资料。借助全文索引,医护人员可以更加便捷地访问相关信息,从而做出更为准确的诊断决策。
任何涉及到大量非结构化文本数据管理和查询的应用都可以考虑采用全文索引来提升搜索效率。
全文索引介绍
在 OceanBase AI 数据库中,全文索引可以应用于 CHAR、VARCHAR 和 TEXT 类型的列。此外,OceanBase AI 数据库允许在主表上建立多个全文索引,并且对于同一列也可以建立多个全文索引。支持创建异步全文索引。
非分区表和分区表上有无主键都可以创建全文索引,创建全文索引限制如下:
- 全文索引仅支持应用于
CHAR、VARCHAR和TEXT类型的列。 - 仅支持创建局部(
LOCAL)全文索引。 - 创建全文索引时不可以指定
UNIQUE关键字。 - 如果要创建涉及多列的全文索引,则必须确保这些列具有相同的字符集。
通过使用这些语法和规则,OceanBase AI 数据库的全文索引功能提供了对文本数据的高效搜索能力。
DML 操作
对于已创建包含全文索引的表,支持 INSERT INTO ON DUPLICATE KEY、REPLACE INTO、多表的更新/删除、以及可更新视图等复杂 DML 操作。
示例如下:
INSERT INTO ON DUPLICATE KEY:
INSERT INTO articles VALUES ('OceanBase', 'Fulltext search index support insert into on duplicate key') ON DUPLICATE KEY UPDATE title = 'OceanBase 4.3.3';REPLACE INTO:
REPLACE INTO articles(title, context) VALUES ('Oceanbase 4.3.3', 'Fulltext search index support replace');多表的更新/删除。
创建表
tbl1。CREATE TABLE tbl1 (a int PRIMARY KEY, b text, FULLTEXT INDEX(b));创建表
tbl2。CREATE TABLE tbl2 (a int PRIMARY KEY, b text);多个表的更新(
UPDATE)语句。UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl1.b = 'dddd', tbl2.b = 'eeee';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl1.b = 'dddd';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl2.b = tbl1.b;多个表的删除(
DELETE)语句。DELETE tbl1, tbl2 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;
可更新视图 DML。
创建视图
fts_view。CREATE VIEW fts_view AS SELECT * FROM tbl1;INSERT语句用于可更新视图。INSERT INTO fts_view VALUES(3, 'cccc'), (4, 'dddd');UPDATE语句用于可更新视图。UPDATE fts_view SET b = 'dddd';UPDATE fts_view JOIN normal ON fts_view.a = tbl2.a SET fts_view.b = 'dddd', tbl2.b = 'eeee';DELETE语句用于可更新视图。DELETE FROM fts_view WHERE b = 'dddd';DELETE tbl1 FROM fts_view JOIN tbl1 ON fts_view.a = tbl1.a AND 1 = 0;
全文索引的分词器和文本分析器
OceanBase AI 数据库的全文索引功能支持多种内置分词器和文本分析器,帮助用户根据业务场景选择最优的文本分词策略。默认分词器为 Space 分词器,其他分词器需通过 WITH PARSER 参数显式指定。除常规分词器插件外,还可选用文本分析器(Analyzer)进行更完整的文本分析。
分词器列表:
- Space 分词器
- Basic English 分词器
- IK 分词器
- Ngram 分词器
- Analyzer 文本分析器
注意
Analyzer 文本分析器从 V4.6.2.1 版本开始支持。
配置方法示例:
在创建或修改表时,通过 CREATE TABLE/ALTER TABLE 语句在为表创建全文索引时,设置参数 WITH PARSER tokenizer_option,指定全文索引的分词器类型。更多分词器的属性参数设置参考 创建索引。
CREATE TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3));
-- 修改现有表的全文索引分词器
ALTER TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3)); -- Ngram示例
Space 分词器(默认)
概念:
- 以空格、标点符号(如逗号、句号)或非字母数字字符(除下划线
_外)为分隔符拆分文本。 - 分词结果仅包含长度在
min_token_size(默认 3)到max_token_size(默认 84)之间的有效词元。 - 中文字符被视为单个字符处理。
适用场景:
- 英文等以空格分隔的语言(如 “apple watch series 9”)。
- 中文以人工添加分隔符的场景(如 “南京 长江大桥”)。
分词效果:
select tokenize ("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM,一平方公里也很小 hello-word h_name", 'space');
+-------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM,一平方公里也很小 hello-word h_name", 'space') |
+-------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello”, "h_name"] |
+-------------------------------------------------------------------------------------------------------------+
示例说明:
- 空格、逗号、句号等符号作为分隔符,中文连续字符视为单词。
Basic English(Beng) 分词器
概念:
- 与 Space 分词器类似,但不保留下划线
_,将其视为分隔符。 - 适用于英文短语分隔,但对无空格术语(如 “iPhone15”)切分效果有限。
适用场景:
- 英文文档的基础搜索(如日志、评论)。
分词效果:
select tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng');
+-----------------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM,邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng') |
+-----------------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello", "name"] |
+-----------------------------------------------------------------------------------------------------------------------+
示例说明:
- 下划线
_被切分,与 Space 分词器的核心差异在于对_的处理。
Ngram 分词器
概念:
- 固定n值分词:默认
n=2,将连续非分隔符字符拆分为长度为n的子序列。 - 分隔符判定规则同 Space 分词器(保留
_和数字字母)。 - 不支持长度限制参数,输出所有可能的
n长度词元。
适用场景:
- 短文本模糊匹配(如用户 ID、订单号)。
- 需要固定长度特征提取的场景(如密码策略分析)。
分词效果:
select tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram');
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize ("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram') |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["邮箱", "ww", "大桥", “ob", "me", "里也", "or", "_n", "千米", "很小", "米长", "ll", "箱x", "公里", "见w", "co", "也很", "1千", "京市", "lo", "江大", "el", "rd", "一平", "方公", "he", "am", "南京", "h_", "市长", "wo", "xx", "长江", "有1", "na", "详见", "平方", "om", "桥有" |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例说明:
- 默认
n=2时,输出所有连续2字符的词元,包括重叠部分。
Ngram2 分词器
概念:
- 支持动态n值范围:通过
min_ngram_size和max_ngram_size参数设置词元长度范围。 - 适用于需要多长度词元覆盖的场景。
适用场景: 同时需要多个固定长度词元的场景。
注意
用 ngram2 分词器时,需注意其内存占用较高,比如设置 min_ngram_size 和 max_ngram_size 参数范围较大时,会生成大量词元组合,可能导致资源消耗过大。
分词效果:
select tokenize ("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]') |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["长江大桥", "大桥1千", "江大桥1千", "市长江大桥", "京市长江", "江大桥1", "南京市长", "市长江大", "大桥1千米", "江大桥1千米", "市长江大桥1", "长江大桥1", "南京市长江", "桥1千米", "南京市长江大", "长江大桥1千", "京市长江大桥", "京市长江大" |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例说明:
- 输出长度在4-6字符的所有连续子序列,且词元可重叠。
IK 分词器
概念:
基于开源工具 IK Analyzer 的中文分词器,支持两种模式:
- Smart 模式:优先输出长词,减少切分数量 (如“南京市”不切分为“南京”“市”)。
- Max Word 模式:输出所有可能的短词(如“南京市”切分为“南京”“市”)。
自动识别英文单词、邮箱、URL(不含
://)、IP 地址等格式。
适用场景:中文分词
业务场景:
电商商品描述搜索(如“华为Mate60”精准匹配)。
社交媒体内容分析(如用户评论的关键词提取)。
Smart 模式:会保证一个字符只会归属一个词汇,没有任何交叠,且保证组成单个词的长度尽可能长,组成的词汇尽可能少。会尝试将数词和量词组合起来,作为一个词汇输出。
select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]');+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]') | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |["邮箱", "hello_word", "192.168.1.1", "hello-word", "长江大桥", "www.baidu.com", "www.xxx.com", "xx@ob.com", "长", "http", "1千米", "详见", "南京市", "有"] | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+max_word 模式: 会把同一个字符包含到不同的分词中, 尽可能多的提供可能的词汇。
select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]');+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]') | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |["米", "长江大桥", "市长", "干", "南京市", "南京", "千米", "xx", "www.xxx.com", "长", "www", "xx@ob.com", "长江", "ob", "XXX", "com", "详见", "l", "有", "大桥", "邮箱"] | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
分词器选择策略
| 业务场景 | 推荐分词器 | 理由 |
|---|---|---|
| 英文商品标题搜索 | Space 或 Basic English | 简单高效,符合英文分词习惯。 |
| 中文商品描述搜索 | IK 分词器 | 精准识别中文术语,支持自定义词典。 |
| 日志模糊匹配(如错误代码) | Ngram 分词器 | 无需词典,覆盖无空格文本的模糊查询需求。 |
文本分析器(Analyzer)
注意
本功能从 V4.6.2.1 版本开始支持。
概念:OceanBase AI 数据库全文索引通过 WITH PARSER analyzer 与 JSON 配置启用 Analyzer。Analyzer 由字符过滤器(CharFilter)、分词器(Tokenizer)和词元过滤器(TokenFilter)组成文本分析管道(pipeline),其中 Tokenizer 负责分词,但整体能力涵盖字符预处理与词元后处理,不限于单一分词器插件所能提供的功能。当前版本提供 standard、english 等多种内置类型。
适用场景:
- 面向多语言、多脚本文本的复杂分析需求,能够适应不同语种和定制化的文本分析任务。
分词效果:
select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'analyzer', '[{"analysis": {"analyzer": "standard"}}]');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'analyzer', '[{"analysis": {"analyzer": "standard"}}]') |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["邮箱", "大", "千米", "很小", "见", "一", "桥", "1", "word", "hello", "平方公里", "www.xxx.com", "也", "ob.com", "h_name", "长", "详", "xx", "长江", "南京市", "有"] |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set
在使用 Analyzer 创建全文索引时,可以使用 TOKENIZE 函数调试分词结果。
Analyzer 的详细操作指引请参见 创建索引 中的 使用文本分析器(Analyzer)创建全文索引 章节。
同步全文索引
可以使用 CREATE TABLE 语句、CREATE FULLTEXT INDEX 语句或 ALTER TABLE 语句创建同步全文索引。同步全文索引在写入主表时同步维护索引,写入后即可被搜索;适合对实时可见性要求高的场景。若需提升写入与查询吞吐、且可接受索引可见延迟,请参见下文 创建异步全文索引。同步与异步的差异对照见 同步与异步索引对比。
使用限制及注意事项
非分区表和分区表上有无主键都可以创建全文索引,创建全文索引限制如下:
- 全文索引仅支持应用于
CHAR、VARCHAR和TEXT类型的列。 - 仅支持创建局部(
LOCAL)全文索引。 - 创建全文索引时不可以指定
UNIQUE关键字。 - 如果要创建涉及多列的全文索引,则必须确保这些列具有相同的字符集。
- 全文索引对 Offline DDL 的支持情况请见Offline DDL。
- 暂不支持创建列存全文索引。
- 同一张表上,同一种索引类型不支持同时存在同步索引与异步索引。
使用 CREATE TABLE 语句创建同步全文索引
通过 CREATE TABLE 语句在创建表时即为表创建同步全文索引,简化语法如下:
CREATE TABLE table_name(column_name column_definition,[column_name column_definition,...]
FULLTEXT [INDEX | KEY] [index_name](column_name)
[WITH PARSER tokenizer_option]
[PARSER_PROPERTIES[=](parser_properties_list)]
[LOCAL]);
tokenizer_option:
SPACE
| NGRAM
| BENG
| IK
| NGRAM2
parser_properties_list:
parser_properties, [parser_properties]
parser_properties:
min_token_size = int_value
| max_token_size = int_value
| ngram_token_size = int_value
| ik_mode = 'char_value'
| min_ngram_size = int_value
| max_ngram_size = int_value
更多 CREATE TABLE 语法信息,参见 CREATE TABLE。
相关参数说明如下:
table_name:指定待创建的表的表名。column_name:指定表的列。column_definition:定义表中各列对应的数据类型。FULLTEXT:指定创建全文索引。注意
仅支持创建局部全文索引。
INDEX | KEY:表示在该语句中,索引关键字使用INDEX或KEY都可以。index_name:可选,指定待创建的索引的索引名。如果未指定,默认索引名与指定的列名相同。WITH PARSER tokenizer_option:可选项,指定全文索引的分词器。取值如下:SPACE:默认值,表示按空格进行分词。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] NGRAM:表示基于 N-Gram(中文)的分词方式。可以指定以下属性:属性 取值范围 ngram_token_size [1, 10] NGRAM2:表示将文本拆成min_ngram_size~max_ngram_size范围的连续字符。属性 取值范围 min_ngram_size [1, 16] max_ngram_size [1, 16] BENG:基于 Beng (基础英文)的分词方式。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] IK:表示基于 IK(中文)的分词方式。当前仅支持utf-8字符集。可以指定以下属性:属性 取值范围 ik_mode smartmax_word
可以使用 TOKENIZE 函数查看文本按照指定的分词器及 Json 形式参数的分词结果。
PARSER_PROPERTIES[=](parser_properties_list):可选项,指定分词器的属性。取值如下:min_token_size:表示最小分词长度,默认值为 3,取值范围是 1 到 16。max_token_size:表示最大分词长度,默认值为 84,取值范围是 10 到 84。ngram_token_size:表示NGRAM的分词长度,只有NGRAM分词器有效,默认值为 2,取值范围是 1 到 10。ik_mode: 表示IK分词器的分词模式。取值如下:smart:默认值,表示词典中的词汇会被用来提高分词的准确性,词典中的词汇边界会被优先考虑,从而可能减少不必要的扩展。max_word:表示在词典中定义的词汇会被识别出来,但不会影响分词的最大化扩展。即使词典中有定义,max_word模式仍然会尝试将文本切分成更多的词汇。
LOCAL:可选,指定创建局部索引。
示例如下:
创建表
tbl1,同时创建全文索引full_idx1_tbl1。CREATE TABLE tbl1(id INT, name VARCHAR(18), date DATE, PRIMARY KEY (id), FULLTEXT INDEX full_idx1_tbl1(name));创建表
tbl2,同时创建全文索引full_idx1_tbl2,指定全文索引的分词器为NGRAM,同时通过PARSER_PROPERTIES设置分词器属性。CREATE TABLE tbl2(id INT, name VARCHAR(18), doc TEXT, FULLTEXT INDEX full_idx1_tbl2(name, doc) WITH PARSER NGRAM PARSER_PROPERTIES=(ngram_token_size=3));
使用 CREATE FULLTEXT INDEX 语句创建同步全文索引
通过 CREATE FULLTEXT INDEX 语句为已有的表创建同步全文索引,语法如下:
CREATE FULLTEXT INDEX index_name ON table_name (column_name, [column_name ...])
[WITH PARSER tokenizer_option]
[PARSER_PROPERTIES[=](parser_properties_list)]
[LOCAL];
tokenizer_option:
SPACE
| NGRAM
| BENG
| IK
| NGRAM2
parser_properties_list:
parser_properties, [parser_properties]
parser_properties:
min_token_size = int_value
| max_token_size = int_value
| ngram_token_size = int_value
| ik_mode = 'char_value'
| min_ngram_size = int_value
| max_ngram_size = int_value
更多 CREATE INDEX 语法信息,参见 CREATE INDEX。
相关参数说明如下:
index_name:指定待添加的索引的索引名。table_name:指定待创建索引的表的表名。column_name:指定对哪些列进行索引,指定多列时,各列之间用英文逗号分隔。WITH PARSER tokenizer_option:可选项,指定全文索引的分词器。取值如下:SPACE:默认值,表示按空格进行分词。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] NGRAM:表示基于 N-Gram(中文)的分词方式。可以指定以下属性:属性 取值范围 ngram_token_size [1, 10] NGRAM2:表示将文本拆成min_ngram_size~max_ngram_size范围的连续字符。可以指定以下属性:属性 取值范围 min_ngram_size [1, 16] max_ngram_size [1, 16] BENG:基于 Beng (基础英文)的分词方式。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] IK:表示基于 IK(中文)的分词方式。当前仅支持utf-8字符集。可以指定以下属性:属性 取值范围 ik_mode smartmax_word
可以使用 TOKENIZE 函数查看文本按照指定的分词器及 Json 形式参数的分词结果。
PARSER_PROPERTIES[=](parser_properties_list):可选项,指定分词器的属性。取值如下:min_token_size:表示最小分词长度,默认值为 3,取值范围是 1 到 16。max_token_size:表示最大分词长度,默认值为 84,取值范围是 10 到 84。ngram_token_size:表示NGRAM的分词长度,只有NGRAM分词器有效,默认值为 2,取值范围是 1 到 10。ik_mode: 表示IK分词器的分词模式。取值如下:smart:默认值,表示词典中的词汇会被用来提高分词的准确性,词典中的词汇边界会被优先考虑,从而可能减少不必要的扩展。max_word:表示在词典中定义的词汇会被识别出来,但不会影响分词的最大化扩展。即使词典中有定义,max_word模式仍然会尝试将文本切分成更多的词汇。
LOCAL:可选项,指定创建局部索引。
示例如下:
创建 tbl3 表后,再创建全文索引 ft_idx1_tbl3。
创建表
tbl3。CREATE TABLE tbl3(col1 INT, col2 VARCHAR(4096));在表
tbl3上创建全文索引ft_idx1_tbl3,指定全文索引的分词器为IK,同时通过PARSER_PROPERTIES设置分词器属性。CREATE FULLTEXT INDEX ft_idx1_tbl3 ON tbl3(col2) WITH PARSER IK PARSER_PROPERTIES=(ik_mode='max_word');
使用 ALTER TABLE 语句创建同步全文索引
通过 ALTER TABLE 语句为已有的表添加同步全文索引,语法如下:
ALTER TABLE table_name ADD FULLTEXT [INDEX | KEY] [index_name](column_name, [column_name ...])
[WITH PARSER tokenizer_option]
[PARSER_PROPERTIES[=](parser_properties_list)]
[LOCAL];
tokenizer_option:
SPACE
| NGRAM
| BENG
| IK
| NGRAM2
parser_properties_list:
parser_properties, [parser_properties]
parser_properties:
min_token_size = int_value
| max_token_size = int_value
| ngram_token_size = int_value
| ik_mode = 'char_value'
| min_ngram_size = int_value
| max_ngram_size = int_value
更多 ALTER TABLE 语法信息,参见 ALTER TABLE。
相关参数说明如下:
table_name:指定待创建索引的表的表名。INDEX | KEY:可选项,表示在该语句中,索引关键字使用INDEX或KEY都可以,缺省值为KEY。index_name:可选项,指定待创建的索引的索引名。如果未指定,默认索引名与指定的列名相同。column_name:指定对哪些列进行索引,指定多列时,各列之间用英文逗号分隔。WITH PARSER tokenizer_option:可选项,指定全文索引的分词器。取值如下:SPACE:默认值,表示按空格进行分词。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] NGRAM:表示基于 N-Gram(中文)的分词方式。可以指定以下属性:属性 取值范围 ngram_token_size [1, 10] NGRAM2:表示将文本拆成min_ngram_size~max_ngram_size范围的连续字符。可以指定以下属性:属性 取值范围 min_ngram_size [1, 16] max_ngram_size [1, 16] BENG:基于 Beng (基础英文)的分词方式。可以指定以下属性:属性 取值范围 min_token_size [1, 16] max_token_size [10, 84] IK:表示基于 IK(中文)的分词方式。当前仅支持utf-8字符集。可以指定以下属性:属性 取值范围 ik_mode smartmax_word
可以使用 TOKENIZE 函数查看文本按照指定的分词器及 Json 形式参数的分词结果。
PARSER_PROPERTIES[=](parser_properties_list):可选项,指定分词器的属性。取值如下:min_token_size:表示最小分词长度,默认值为 3,取值范围是 1 到 16。max_token_size:表示最大分词长度,默认值为 84,取值范围是 10 到 84。ngram_token_size:表示NGRAM的分词长度,只有NGRAM分词器有效,默认值为 2,取值范围是 1 到 10。ik_mode: 表示IK分词器的分词模式。取值如下:smart:默认值,表示词典中的词汇会被用来提高分词的准确性,词典中的词汇边界会被优先考虑,从而可能减少不必要的扩展。max_word:表示在词典中定义的词汇会被识别出来,但不会影响分词的最大化扩展。即使词典中有定义,max_word模式仍然会尝试将文本切分成更多的词汇。
LOCAL:可选项,指定创建局部索引。
示例如下:
创建表 tbl4 后,然后再添加全文索引 ft_idx1_tbl4。
创建表
tbl4。CREATE TABLE tbl4(col1 INT, col2 TEXT);为表
tbl4添加全文索引ft_idx1_tbl4,指定全文索引的分词器为BENG,同时通过PARSER_PROPERTIES设置分词器属性。ALTER TABLE tbl4 ADD FULLTEXT INDEX ft_idx1_tbl4(col2) WITH PARSER BENG PARSER_PROPERTIES=(min_token_size=2, max_token_size=64);
异步全文索引
说明
异步全文索引从 V4.6.2.1 版本开始支持。
注意
异步全文索引在当前版本为实验特性,不支持生产环境使用。
异步全文索引(ASYNC FULLTEXT)将索引维护改为后台增量刷新,以一定的可见延迟换取写入与查询性能的提升。当前主要用于混合搜索场景;查询保证最终一致性,不保证强一致与实时可见。更多差异见下文对照表。
开启与使用
异步索引功能默认关闭,需通过 _enable_async_index 配置项开启:
ALTER SYSTEM SET _enable_async_index = true;
创建异步全文索引需要在现有全文索引语法前增加 ASYNC 关键字,支持随表创建与后建:
CREATE TABLE tbl5(col1 INT, col2 TEXT)
ASYNC FULLTEXT INDEX ft_idx1_tbl5(col2)
WITH PARSER BENG
PARSER_PROPERTIES=(min_token_size=2, max_token_size=64);
端到端示例见下文 异步全文索引与混合搜索。
同步与异步索引对比
| 对比项 | 同步全文索引 | 异步全文索引 |
|---|---|---|
| DDL 关键字 | FULLTEXT |
ASYNC FULLTEXT |
| 索引维护时机 | 写入主表时同步维护 | 后台增量刷新,非实时写入索引 |
| 数据可见性 | 写入后即可搜索 | 最终一致,可能存在可见延迟 |
| 写入/查询性能 | 高吞吐场景下可能成为性能瓶颈 | 以可见延迟换取更高的写入与查询性能 |
| 适用场景 | 全文搜索/混合搜索 | 主要用于混合搜索 |
| 分词器 | WITH PARSER / PARSER_PROPERTIES |
与同步全文索引相同 |
| 表类型 | 非分区表、分区表均可 | 仅支持堆表 |
UPDATE 行为 |
按常规更新处理 | 转换为 DELETE + INSERT |
使用限制及注意事项
- 仅支持堆表(
ORGANIZATION = HEAP)。 - 当前支持异步全文索引与异步搜索索引;异步向量索引、异步普通索引暂不支持。
- 同一张表上,同一种索引类型不支持既有同步索引又有异步索引。
- 对包含异步索引的表,
UPDATE会转换为DELETE+INSERT。
自动刷新与合并
异步索引的自动刷新与合并通过表级配置设置。当前支持以下配置项:
| 配置项 | 类型 | 取值范围 | 默认值 | 含义 |
|---|---|---|---|---|
ASYNC_REFRESH_INTERVAL |
INT(秒) | [1, 60],-1 |
5 |
控制异步索引后台增量刷新服务的扫描周期。每隔该间隔检查表中是否有新的增量数据,若有则触发增量刷新任务。-1 表示禁止后台刷新。该参数从 V4.6.2.1 版本开始支持。 |
REFRESH_ON_ERROR |
枚举 | SKIP / ABORT |
ABORT |
控制增量刷新遇到单行异常数据时的处理策略。ABORT 表示整次刷新失败并阻塞后续增量,适合对数据完整性要求极高的场景;SKIP 表示跳过异常行并继续刷新,不阻塞其他行及其他索引,该行不会写入索引。注意:资源或环境类错误即使在 SKIP 模式下也不会跳过。该参数从 V4.6.2.1 版本开始支持。 |
DELETE_PURGE_THRESHOLD |
INT | [20, 50] |
33 |
控制异步索引中已删除数据的清理阈值。当已删除行数占总行数的比例超过该阈值时,触发合并以清理已删除的数据。 |
MERGE_SEGMENT_THRESHOLD |
INT | [2, 48] |
10 |
控制异步索引合并策略中的段(Segment)数阈值。当增量刷新产生的 Segment 数量超过该值时,触发合并,将多个小 Segment 合并为较大的 Segment。 |
注意
随表创建异步索引时,向表中写入数据不会校验这些数据能否写入该索引。若存在无法写入索引的行,在默认 ABORT 策略下会卡住增量刷新,导致后续增量也无法通过该索引查询。此时可将 REFRESH_ON_ERROR 设为 SKIP,以跳过异常行并继续刷新。
-- 随表建设置刷新周期
CREATE TABLE doc_async (
c1 INT,
content VARCHAR(255),
ASYNC FULLTEXT INDEX idx_content(content)
) ORGANIZATION HEAP ASYNC_INDEX_PARAMS = 'ASYNC_REFRESH_INTERVAL=10';
-- 只修改刷新间隔,其他配置保持不变
ALTER TABLE doc_async SET ASYNC_INDEX_PARAMS = 'ASYNC_REFRESH_INTERVAL=10';
-- 跳过增量刷新中的异常行
ALTER TABLE doc_async SET ASYNC_INDEX_PARAMS = 'REFRESH_ON_ERROR=SKIP';
-- 同时修改多个配置
ALTER TABLE doc_async SET ASYNC_INDEX_PARAMS = 'ASYNC_REFRESH_INTERVAL=10, REFRESH_ON_ERROR=SKIP, DELETE_PURGE_THRESHOLD=30, MERGE_SEGMENT_THRESHOLD=8';
完整语法说明请参见 ALTER TABLE。
手动合并
除按 MERGE_SEGMENT_THRESHOLD 自动合并外,还可通过 DBMS_ASYNC_INDEX 系统包手动触发合并:
-- 手动触发合并
CALL DBMS_ASYNC_INDEX.FORCEMERGE('doc_async');
详细语法与参数请参见 DBMS_ASYNC_INDEX 概述。
使用示例
以下分别给出同步全文索引与异步全文索引的示例。
同步全文索引
在本示例中会定义一个表以保存文档资料,并为文档设置全文索引。利用全文索引可快速匹配包含期望关键字的文档,并按相似性从高到低排序。
创建表。
CREATE TABLE Articles ( id INT AUTO_INCREMENT, title VARCHAR(255) , content TEXT , PRIMARY KEY (id), FULLTEXT ft1 (content) WITH PARSER SPACE );插入数据。
INSERT INTO Articles (title, content) VALUES ('OceanBase AI 数据库overview', 'OceanBase AI 数据库is an AI-native search database. It unifies relational, vector, text, JSON and GIS in a single engine, enabling hybrid search and in-database AI workflows.'), ('Full-Text Search in Databases', 'Full-text search allows for searching within the text of documents stored in a database. It is particularly useful for finding specific information quickly.'), ('Advantages of Using OceanBase AI 数据库', 'OceanBase AI 数据库offers several advantages such as high performance, reliability, and ease of use. ');查询表。
select * from Articles;+----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | title | content | +----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 1 | OceanBase AI 数据库overview | OceanBase AI 数据库is an AI-native search database. It unifies relational, vector, text, JSON and GIS in a single engine, enabling hybrid search and in-database AI workflows. | | 2 | Full-Text Search in Databases | Full-text search allows for searching within the text of documents stored in a database. It is particularly useful for finding specific information quickly. | | 3 | Advantages of Using OceanBase AI 数据库| OceanBase AI 数据库offers several advantages such as high performance, reliability, and ease of use. | +----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.002 sec)查询匹配的文档。
select id,title, content,match(content) against('OceanBase AI 数据库database') score from Articles where match(content) against('OceanBase AI 数据库database');+----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | id | title | content | score | +----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ | 1 | OceanBase AI 数据库overview | OceanBase AI 数据库is an AI-native search database. It unifies relational, vector, text, JSON and GIS in a single engine, enabling hybrid search and in-database AI workflows. | 0.4570384669555348 | | 3 | Advantages of Using OceanBase AI 数据库| OceanBase AI 数据库offers several advantages such as high performance, reliability, and ease of use. | 0.240174672489083 | | 2 | Full-Text Search in Databases | Full-text search allows for searching within the text of documents stored in a database. It is particularly useful for finding specific information quickly. | 0.20072992700729927 | +----+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+ 3 rows in set (0.003 sec)利用 EXPLAIN 命令,查看查询计划并分析其性能。
explain select id,title, content,match(content) against('OceanBase AI 数据库database') score from Articles where match(content) against('OceanBase AI 数据库database');+-------------------------------------------------------------------------------------------------------------------------------------------------+ | Query Plan | +-------------------------------------------------------------------------------------------------------------------------------------------------+ | ============================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | -------------------------------------------------------------- | | |0 |SORT | |4 |139 | | | |1 |└─TEXT RETRIEVAL SCAN|articles(ft1)|4 |138 | | | ============================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output([articles.id], [articles.title], [articles.content], [MATCH(articles.content) AGAINST('OceanBase AI 数据库database')]), filter(nil), rowset=16 | | sort_keys([MATCH(articles.content) AGAINST('OceanBase AI 数据库database'), DESC]) | | 1 - output([articles.id], [articles.content], [articles.title], [MATCH(articles.content) AGAINST('OceanBase AI 数据库database')]), filter(nil), rowset=16 | | access([articles.id], [articles.content], [articles.title]), partitions(p0) | | is_index_back=true, is_global_index=false, | | calc_relevance=true, match_expr(MATCH(articles.content) AGAINST('OceanBase AI 数据库database')), | | pushdown_match_filter(MATCH(articles.content) AGAINST('OceanBase AI 数据库database')) | +-------------------------------------------------------------------------------------------------------------------------------------------------+ 15 rows in set (0.002 sec)
异步全文索引与混合搜索
本示例创建带异步全文索引与向量索引的堆表,并使用 HYBRID_SEARCH 进行全文搜索及全文与向量混合搜索。dsl_string 语法与同步全文索引场景一致。更多混合搜索场景请参见 混合搜索。
- 创建异步全文索引。
CREATE TABLE doc_async (
c1 INT,
vector VECTOR(3),
content VARCHAR(255),
VECTOR INDEX idx_vec(vector) WITH (distance=l2, type=hnsw_sq, lib=vsag),
ASYNC FULLTEXT INDEX idx_content(content)
) ORGANIZATION HEAP;
CREATE TABLE doc_async (
c1 INT,
vector VECTOR(3),
content VARCHAR(255),
VECTOR INDEX idx_vec(vector) WITH (distance=l2, type=hnsw_sq, lib=vsag)
) ORGANIZATION HEAP;
ALTER TABLE doc_async ADD ASYNC FULLTEXT INDEX idx_content(content);
-- 或
CREATE ASYNC FULLTEXT INDEX idx_content ON doc_async(content);
- 插入数据。
INSERT INTO doc_async VALUES
(1, '[1,2,3]', 'oceanbase Elasticsearch database'),
(2, '[1,2,1]', 'oceanbase mysql database'),
(3, '[1,1,1]', 'oceanbase oracle database');
- 全文搜索(走异步全文索引)。
SELECT c1, content FROM HYBRID_SEARCH(
TABLE doc_async,
'{
"query": {
"match": {"content": "oceanbase mysql"}
}
}'
);
- 全文与向量混合搜索。
SELECT c1, content FROM HYBRID_SEARCH(
TABLE doc_async,
'{
"query": {
"match": {"content": "oceanbase mysql"}
},
"knn": {
"field": "vector",
"k": 3,
"query_vector": "[1,2,3]"
},
"rank": {
"rrf": {
"rank_constant": 60
}
}
}'
);