当前位置: 首页 > news >正文

深入剖析 Doris 倒排索引(上):原理与应用全解析​


大数据处理与分析的场景中,快速且精准的查询能力是衡量数据系统优劣的关键指标之一。Apache Doris 的倒排索引功能,就像一把 “利刃”,为数据检索与分析效率的提升提供了强大支持。本文上篇将围绕 Doris 倒排索引的基础原理与功能特性展开,带你深入了解这一技术的核心要点。

一、倒排索引基础:构建数据检索的基石

(一)倒排索引文件:存储结构的奥秘

倒排索引是针对 Doris 中 segment 级别的数据文件构建的,其核心作用是将数据中的关键词与包含该关键词的文档建立关联,从而实现高效检索。在 Doris 中,倒排索引文件存在两种类型:V1 和 V2,不同版本对默认索引文件类型的设置有所差异。

  • 版本差异与配置:Doris 3.0 版本之前,默认使用 V1 类型的倒排索引文件;从 3.0 版本开始,默认切换为 V2 类型。在 3.0 和 2.1 版本中,用户可以通过配置properties inverted_index_storage_format=v1/v2来灵活选择索引文件类型,但需要注意的是,Doris 2.0 版本并不支持此配置。

  • 文件结构对比:以实际文件存储为例,V1 版本的索引文件结构较为分散,在数据存储目录下,一个数据段可能对应多个.idx 文件。例如:

└── [4.0K]  11991└── [ 36K]  2110008962├── [ 78M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12129.idx├── [8.6M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12131.idx├── [ 19M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12133.idx├── [ 33K]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12135.idx├── [6.1M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12137.idx├── [ 27M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12139.idx├── [ 13M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12141.idx├── [ 55K]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12143.idx├── [2.4M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12145.idx├── [2.5M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12147.idx├── [2.7M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0_12149.idx├── [375M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0.dat

而 V2 版本对文件进行了整合优化,减少了文件数量,例如:

└── [4.0K]  11991└── [ 36K]  2110008962├── [178M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0.idx├── [375M]  020000000000016a1c464dcb7093448cbaff369795c7e79b_0.dat

这种结构上的差异,使得 V2 版本在存储和查询性能上通常更具优势。

(二)支持与受限类型:明确应用边界

倒排索引并非适用于所有数据类型,了解其支持和受限类型,有助于我们在实际应用中合理使用。

  • 支持类型

    • 文本类型:CHAR、STRING、VARCHAR、TEXT 等文本类型,是倒排索引发挥全文检索和查询加速功能的 “主战场”。例如,在日志分析场景中,对包含大量文本信息的日志内容字段建立倒排索引,能够快速定位包含特定关键词的日志记录。

    • 数组类型:ARRAY类型可用于特定函数的查询加速,如array_contains(判断数组是否包含某个元素)、array_overlaps(判断两个数组是否有重叠元素)等函数。假设存在一个存储用户兴趣标签的数组字段,通过倒排索引可以加速查询包含特定兴趣标签的用户数据。

    • 数值与日期类型:INT、BIGINT、DECIMAL 等数值类型,以及 DATE、DATEV2、DATETIME、DATETIMEV2 等日期类型,倒排索引能够有效提升基于这些类型字段的查询速度,如数值范围查询和日期筛选查询。

  • 受限类型

    • 浮点类型:FLOAT、DOUBLE 等浮点类型目前暂不支持倒排索引,后续会考虑开放支持。

    • 复杂类型:MAP、STRUCT、JSON、HLL、BITMAP、QUANTILE_STATE、AGG_STATE 等复杂数据类型,由于结构复杂,暂不适合使用倒排索引。

    • 表模型限制:在 AGGREGATE 表模型和未开启 MOW(Materialized on Write)的 UNIQUE 表模型中,倒排索引只能应用于 Key 列,非 Key 列无法建立倒排索引。

二、全文检索:精准匹配的强大武器

(一)索引构建:精细配置的艺术

在 Doris 中创建全文索引,需要在建表语句中添加特定语法:

CREATE TABLE table_name
(column_name1 TYPE1,column_name2 TYPE2,column_name3 TYPE3,INDEX idx_name1(column_name1) USING INVERTED [PROPERTIES(...)] [COMMENT 'your comment'],INDEX idx_name2(column_name2) USING INVERTED [PROPERTIES(...)] [COMMENT 'your comment']
)
table_properties;

其中,PROPERTIES是全文检索模式下的必选项,通过它可以对索引进行多种精细配置:

  • parser(分词器):分词器决定了文本的分词方式,不同的分词器适用于不同的语言和场景。

    • 不指定分词器:表示不对文本进行分词处理,适用于不需要分词的特殊场景。
    • english(英文分词):适用于被索引列为英文的情况,它会使用空格和标点符号进行分词,性能较高。例如,对于英文文档中的句子 “Hello, world! This is a test.”,会被分词为 “Hello”、“world”、“This”、“is”、“a”、“test”。
    • chinese(中文分词):专为中文设计,适用于以中文为主的字段。不过,由于中文分词的复杂性,其性能相对低于 english 分词器。例如,“我爱北京天安门” 可能会被分词为 “我”、“爱”、“北京”、“天安门”。
    • unicode(多语言混合分词):能够处理中英文混合、多语言混合的文本内容,支持邮箱、IP 地址、字符数字混合内容的分词,也支持中文按字符分词。例如,对于文本 “我的邮箱是 example@example.com,IP 地址是 192.168.1.1”,能够准确分词并建立索引。
  • parser_mode(中文分词模式):该属性仅在parser = chinese时生效,用于调整中文分词的粒度。

    • fine_grained(细粒度):会分出更多、更短的词。例如,“武汉市长江大桥” 会被分成 “武汉”、“武汉市”、“市长”、“长江”、“长江大桥”、“大桥” 等 6 个词。
    • coarse_grained(粗粒度):分出的词更少、更长,“武汉市长江大桥” 会被分成 “武汉市”、“长江大桥” 2 个词。默认情况下,中文分词采用粗粒度模式。
  • support_phrase(是否支持短语查询加速)

    • true:开启短语查询加速功能,能够支持MATCH_PHRASE算子进行短语查询,但会使索引体积增大。
    • false:不支持短语查询,有助于节省存储空间,默认值为 false。
  • char_filter(文本预处理):用于指定文本在分词前的预处理行为。

    • char_filter_type:目前仅支持char_replace类型。
    • char_filter_pattern:指定需要被替换的字符,如 “.” 和 “” 或者 “.” ,需要注意的是,这里的字符只能是 ascii 码,不能使用其他 unicode 字符。
    • char_filter_replacement:指定替换成的字符,默认是空格。
  • ignore_above(限制索引长度):设置未分词字符串索引的最大长度,长度超过该值的字符串将不会被索引。对于字符串数组,该限制分别作用于每个元素,默认值为 256 字节。

  • lower_case(是否转换为小写)

    • true:将文本转换为小写,方便进行忽略大小写的匹配操作,在 2.0.7 和 2.1.2 版本之后默认值为 true。
    • false:不进行小写转换,这是旧版本的默认设置。
  • stopwords(停用词配置):默认停用词表包含如 “is”、“the”、“a” 等无意义词汇,在写入和查询时会忽略这些词。将其设置为 none 时,表示不使用停用词表。

(二)检索算子:多样匹配的实现

Doris 提供了丰富的全文索引检索算子,以满足不同场景下的查询需求:

  • MATCH_ANY:用于匹配包含任一关键词的文档。例如,执行查询语句SELECT * FROM table_name WHERE content MATCH_ANY 'keyword1 keyword2';,会返回content列中包含keyword1keyword2中至少一个的所有行。也就是说,只要文档中出现了keyword1或者keyword2 ,或者两者都出现,都会被匹配出来。

  • MATCH_ALL:用于匹配同时包含所有关键词的文档。如SELECT * FROM table_name WHERE content MATCH_ALL 'keyword1 keyword2';,只有content列中同时出现keyword1keyword2的行才会被返回。

  • MATCH_PHRASE:实现短语匹配,要求关键词按顺序相邻出现。例如,执行SELECT * FROM table_name WHERE content MATCH_PHRASE 'keyword1 keyword2';,只有像 “keyword1 keyword2”、“wordx keyword1 keyword2”、“wordx keyword1 keyword2 wordy” 这样keyword2紧跟在keyword1后面的文档才能匹配成功。需要注意的是,使用该算子必须在PROPERTIES中开启"support_phrase" = "true"

  • MATCH_PHRASE slop:松散短语匹配,允许关键词之间存在一定间隔,间隔词数不超过指定的slop值。例如,SELECT * FROM table_name WHERE content MATCH_PHRASE 'keyword1 keyword2 ~3'; ,当slop=3时,“keyword1 keyword2”、“keyword1 a keyword2”、“keyword1 a b c keyword2” 等都能匹配,因为keyword1keyword2中间隔的词分别是 0、1、3,都不超过 3。此外,当slop > 0时,不再要求keyword1keyword2的顺序固定,像 “keyword2 a b c keyword1” 也能匹配。如果使用正号 “+”,则会进入顺序严格模式,要求关键词必须按指定顺序出现 。

  • MATCH_PHRASE_PREFIX:短语匹配,但最后一个词允许进行前缀匹配。例如,SELECT * FROM table_name WHERE content MATCH_PHRASE_PREFIX 'keyword1 keyword';,“keyword1 keyword2abc”、“keyword1 keyword2” 能匹配,因为 “keyword2abc” 和 “keyword2” 都满足 “keyword” 的前缀匹配条件,而 “keyword1 keyword3” 则无法匹配。当只指定一个词进行查询时,如SELECT * FROM table_name WHERE content MATCH_PHRASE_PREFIX 'keyword1';,会退化为该词的前缀匹配模式。

  • MATCH_REGEXP:进行正则匹配查询,需要注意的是,这里的查询词不会进行分词处理。例如,SELECT * FROM table_name WHERE content MATCH_REGEXP '^key_word.*';,会匹配任何以 “key_word” 开头的词,像 “key_word”、“key_words” 等,但 “keyword” 不会匹配,即使 “_” 是停用词。

  • MATCH_PHRASE_EDGE:对标 ES 的 query_string,实现边缘短语匹配,用于匹配以指定短语作为完整单词边界的文档。例如,有以下几行数据(字段名为content):

    • “The quick brown fox jumps over the lazy dog.”
    • “Spotlight on new lighthouse project.”
    • “Research shows search engine optimization is key.”
    • “Doris is a powerful SQL database.”
      当执行查询
      当执行查询content MATCH_PHRASE_EDGE'search engine optim'时:
    • 第一个词 “search” 被视为后缀词,会匹配 “research” 和 “search”;
    • 中间词 “engine” 要求精确匹配;
    • 最后一个词 “optim” 被视为前缀词,会匹配 “optimization”;
    • 并且要求这三个词紧挨着出现。所以,只有文档 3“Research shows search engine optimization is key.” 会被匹配出来。

三、查询加速:提升检索效率的核心

(一)支持的运算符和函数:加速的范围

倒排索引能够对多种运算符和函数的查询起到加速作用,同时与 BloomFilter 索引、NGram BloomFilter 索引在支持的运算符上存在差异:

运算符 / 函数倒排索引BloomFilter 索引NGram BloomFilter 索引
=YESYESNO
!=YESNONO
INYESYESNO
NOT INYESNONO
>, >=, <, <=, BETWEENYESNONO
IS NULLYESNONO
IS NOT NULLYESNONO
LIKENONOYES
array_containsYESNONO
array_overlapsYESNONO
is_ip_address_in_rangeYESNONO

例如,在进行数值范围查询SELECT * FROM table WHERE age > 18;时,倒排索引可以快速过滤出符合条件的行;使用array_contains函数查询SELECT * FROM table WHERE tags ARRAY_CONTAINS 'sports';,倒排索引同样能加速查询过程。不过,需要注意的是,LIKE运算符需要通过 NGram BloomFilter 索引加速,并且要在在FE开启set enable_function_pushdown = true

(二)倒排索引加速查询的原理

倒排索引加速查询的核心逻辑,是通过提前过滤掉不需要加载的行,大幅减少数据读取时的 I/O 以及 CPU 资源消耗。比如在一张存储用户信息的大表中,若对 “用户标签” 字段建立倒排索引,当执行SELECT * FROM users WHERE user_tags MATCH_ANY '文字1,文字2'查询时,倒排索引能迅速定位到包含 “文字1” 或 “文字2” 标签的用户所在行,无需扫描全表数据,直接跳过无关行,从而显著提升查询效率。

通过上篇的介绍,相信你已经对 Doris 倒排索引的原理与应用有了较为全面的认识。然而在实际使用过程中,难免会遇到各种问题。下篇将聚焦倒排索引常见问题,为你提供详细的解决方案,助你轻松应对使用中的挑战,敬请期待!

http://www.xdnf.cn/news/590239.html

相关文章:

  • 腾讯2025年校招笔试真题手撕(三)
  • 嵌入式学习笔记 - 关于ARM编辑器compiler version 5 and compiler version 6
  • 软考高项考前48小时冲刺:核心考点记忆 + 错题复盘 + 3 科重点
  • 养生指南:五维提升健康品质
  • 基于cornerstone3D的dicom影像浏览器 第二十一章 显示DICOM TAGS
  • Paimon和Hive相集成
  • Java基础 Day18
  • Redis 是否适合像 MySQL 一样当数据库使用?
  • 单一职责原则 (Single Responsibility Principle, SRP)
  • html主题切换小demo
  • Oracle 中 SHRINK 与 MOVE 操作的比较
  • NR 通讯的整体架构
  • PyTorch可视化工具——使用Visdom进行深度学习可视化
  • Jetson:aarch64平台编译onnxruntime使用GPU
  • 【GESP】C++三级真题 luogu-B4038 [GESP202409 三级] 平衡序列
  • Flask 路由跳转机制:url_for生成动态URL、redirect页面重定向
  • 基于 ZU49DR FPGA 的无线电射频数据采样转换开发平台核心板
  • Docker-Mysql
  • LLaMA-Factory微调LLM-Research/Llama-3.2-3B-Instruct模型
  • 基于多目标优化的样本调度适应度函数设计
  • 7.1.查找的基本概念
  • 高等数学-无穷级数
  • Unity飞机大战-射击类游戏3D虚拟
  • Athena 执行引擎:在线服务计算的效率王者
  • pandas :从入门到进阶的系统实践笔记
  • 错误: gdalbuildvrt 命令未找到————的问题
  • 数字孪生驱动的离散制造智能升级:架构设计与工程实践
  • C++:关联式容器map容器,multimap容器
  • ssrf漏洞学习
  • 并发编程:各种锁机制、锁区别、并发工具类深刻总结