当您需要在海量数据中执行LIKE模糊匹配或MATCH关键词检索时,标准的查询方式往往因全表扫描与字符串比较而导致性能瓶颈。列存索引(IMCI)提供了一系列专门针对字符串模糊搜索的优化功能,通过粗粒度索引、倒排索引和SIMD指令集等技术,将查询性能提升数个数量级,实现复杂场景下的毫秒级响应。本文将为您详细介绍列存索引(IMCI)提供的多种字符串搜索优化方案,并提供决策指引和最佳实践,帮助您根据具体业务场景选择最合适的优化策略。
优化方案对比
为了帮助您快速决策,下表对比了不同优化方案的核心原理、适用场景及优缺点。
优化项 | 适用LIKE模式 | 核心原理 | 优点 |
Like Pruner |
| 利用列存数据块的Min/Max值和Bloom Filter进行快速过滤。 | 对前缀和包含匹配有普适性加速效果。 |
Bloom Like |
| 通过构建token或ngram bloom filter并结合Like Pruner来优化 | 适用于字符串差异较大的情况,尤其适合中文等语言。 |
Const Like | 任意含常量的模式 | 预计算 | 默认开启,对降低CPU使用率有一定帮助,尤其是在循环或长常量场景。 |
SIMD Like | 任意模式 | 利用CPU的并行处理能力,将原本逐个字符的串行比较,升级为用单条指令一次性并行比较一大块字符,从而实现加速。支持大小写,但不支持重音。 | 对长文本匹配性能提升显著。 |
Match Like |
| 将 | 性能提升巨大,尤其适合海量文本的包含匹配。 |
配置LIKE查询优化
本章节将详细介绍如何配置和使用针对LIKE查询的各项优化功能。
Like Pruner:数据块裁剪
利用列存数据块的粗粒度索引(Min/Max值和Bloom Filter)快速跳过不包含目标数据的数据块,减少不必要的扫描和匹配操作。
此功能默认开启,自动对以下两种模式生效:
LIKE 'xxx'与LIKE 'xxx%':利用数据块的Min/Max值与常量前缀进行范围比较,快速跳过不匹配的数据块。LIKE '%xxx%':若已为该列创建Bloom Filter,则利用Bloom Filter快速判断数据块中是否存在目标字符串,若不存在则直接跳过。
您可以通过以下参数控制该功能的开启状态:
参数名 | 级别 | 说明 |
| Global/Session | 控制是否开启
|
Bloom Like:为LIKE '%xxx%'加速
通过为指定列创建token或ngram类型的Bloom Filter,为Like Pruner提供更高效的数据块过滤能力,优化LIKE '%xxx%'模式的查询。
token bloom filter:按非字母和非数字字符对字符串进行分词,适合英文或代码等场景。例如,
'PolarDB-IMCI'会被分割为PolarDB和IMCI。ngram bloom filter:按指定长度(N)连续切分字符串,适合中日韩等无明显分隔符的语言。例如,当N=2时,
'云原生数据库'会被分割为云原、原生、生数、数据、据库。
创建语法:更多信息,请参见设置列索引查询过滤算法。
-- 为列创建Token Bloom Filter
ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'PRUNER_TOKEN_BLOOM=1';
-- 为列创建Ngram Bloom Filter,N设为2
ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'PRUNER_NGRAM_BLOOM=2';使用建议:
ngram的size应小于或等于LIKE查询中最短的常量字符串长度。如果size大于常量长度,该优化将不会生效。Bloom Like适用于字符串差异较大的情况,尤其适用于中文等语言。一般而言,当字段主要包含中文时,可以使用ngram bloom filter过滤器以提高处理速度。
Const Like:常量预计算
在LIKE查询的匹配过程中,避免对常量字符串在每一行都重复进行编码计算,从而降低CPU消耗。
此功能默认开启,在LIKE模式包含长常量字符串时,对降低CPU使用率有一定帮助。
参数名 | 级别 | 说明 |
| Global/Session | 控制是否开启
|
SIMD Like:并行字符串匹配
使用CPU的SIMD(单指令多数据流)指令集重写字符串匹配算法,实现并行计算,显著提升长文本的匹配性能。
由于可能存在与标准字符集编码的细微语义差异,此功能默认关闭,需您根据业务场景显式开启。
不支持重音匹配:此优化不支持重音不敏感的精确匹配。例如,在utf8mb4_0900_ai_ci编码下,标准LIKE会将'a'和'á'视为相等,但开启SIMD Like后可能视其为不相等。请在确认业务场景无需严格重音匹配时才开启。
参数名 | 级别 | 说明 |
| Global/Session | 控制是否开启
|
Match Like:用全文索引加速LIKE
将LIKE '%xxx%'查询智能改写为基于IMCI全文索引的MATCH ... AGAINST查询,利用倒排索引实现海量文本的高性能包含匹配,性能提升可达数个数量级。
工作原理:
索引阶段:对指定列创建全文索引,IMCI会将每行数据按
ngram分词并构建倒排索引。查询阶段:将
LIKE模式中的常量也按相同的ngram规则分词,然后通过倒排索引快速找到包含所有分词的行,最后再用LIKE条件进行精确过滤。
基于ngram的倒排索引在加速LIKE查询的过程中,其结果与原生LIKE查询并不完全等价,可能引入伪匹配(False Positives)。
以ngram(2)索引为例,当查询条件为LIKE '%abc%'时,该条件会被拆分为'ab'和'bc'。因此,一个内容为"abbc"的数据行也会被倒排索引召回,因为其分词结果('ab','bb','bc')同时包含了'ab'和'bc',但显然这不符合LIKE '%abc%'的精确语义。
为确保结果的绝对准确性,IMCI默认采用两阶段策略:首先通过FtsTableScan算子利用倒排索引快速召回一个候选结果集,然后再通过原生的LIKE条件进行二次过滤,以精确剔除所有伪匹配的行。
然而,在某些场景下,例如在大表查询且LIKE条件过滤性较差的情况下,召回的候选结果集可能非常庞大,从而导致二次过滤成为新的性能瓶颈,反而降低整体效率。针对这种情况,IMCI提供了一个优化参数,允许跳过二次过滤的逻辑,仅执行倒排索引的查找和交集计算。此举能够有效避免大量的字符比对,显著提升查询效率,但相应地,最终结果中可能包含这些伪匹配项。
配置方法:
您需要先为目标列创建IMCI全文索引,然后通过参数开启Match Like功能。
创建语法:更多信息,请参见IMCI全文索引使用说明。
-- 为列创建ngram全文索引,ngram长度为3
ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'imci_fts(type=1 len=3)';参数配置:
参数名 | 级别 | 说明 |
| Global/Session | 控制是否开启
|
配置MATCH全文检索优化
为解决MySQL原生全文索引在更新频繁、高并发和海量数据场景下的性能瓶颈。IMCI基于主流的倒排索引技术和标记删除方案,重构了全文检索功能。即使在频繁更新的场景下,也能保证写入性能不受影响,并满足海量数据下的高并发、毫秒级检索需求。
使用方法:
为目标列创建IMCI全文索引后,即可使用标准的MATCH ... AGAINST语法进行查询。更多信息,请参见IMCI全文索引使用说明。
-- 示例:为content列创建全文索引
ALTER TABLE articles MODIFY content TEXT COMMENT 'imci_fts(type=2)';
-- 使用全文索引进行查询
SELECT * FROM articles WHERE MATCH(content) AGAINST('云原生');