DDS索引
华为云文档数据库服务(Document Database Service, DDS)的索引是基于MongoDB协议开发的高性能数据检索结构,支持单字段、复合、TTL、稀疏、部分等索引类型,并扩展了隐藏索引、通配符索引等企业级特性。其核心目标是通过减少全表扫描、优化排序和聚合操作,显著提升查询性能。DDS完全兼容MongoDB的索引机制与查询语法,底层采用高性能云原生存储引擎,并结合分片集群与副本集架构,实现高可用性与弹性扩展。
为什么需要DDS索引?
- 加速查询:在百万级文档中,索引可将查询响应时间从分钟级降至毫秒级(时间复杂度从O(n)降至O(log n))。
- 支持复杂操作:
- 排序优化:索引可直接返回排序结果,避免全表扫描(如db.collection.find().sort({field:1}))。
- 聚合加速:复合索引可优化$group和$match操作,减少中间数据量。
- 企业级需求:物联网(IoT)场景中,设备日志存储需处理TB级数据,索引是实时查询的性能保障。
DDS索引的优势是什么?
DDS索引的核心优势在于其全兼容、高弹性、精细化控制与智能化性能保障的有机结合。具体请查看表1。
DDS索引的使用场景
| 应用场景 | 查询需求 | 索引策略 | 技术价值 |
|---|---|---|---|
| 电商平台商品搜索与推荐 | 多维度筛选(分类、价格区间、品牌、评分)。 | 复合索引 {category: 1, price: 1, brand: 1} | 避免全表扫描,实现毫秒级商品列表加载和排序。 |
| 金融交易流水审计 | 按时间范围查询特定用户交易记录。 | 复合索引 {userId: 1, timestamp: -1} | 快速定位用户最新交易,满足合规审计实时性要求。 |
| 物流轨迹实时追踪 | 根据运单号查询最新位置及历史轨迹。 | 唯一索引 {trackingNumber: 1} + TTL索引 {createdAt: 1} | 保证查询效率的同时优化存储空间,自动清理过期数据。 |
| 内容管理系统标签检索 | 按多个标签组合过滤文章内容。 | 多键索引 tags 字段 | 支持数组元素快速匹配,实现灵活的内容分类和精准检索。 |
| 监控告警时序数据处理 | 存储设备监控指标,定期清理过期数据。 | TTL索引 {createdAt: 1}(expireAfterSeconds: 604800) | 自动化数据生命周期管理,减少手动维护成本。 |
| 地理信息服务(LBS) | 查找附近商家,基于位置查询。 | 地理空间索引(2dsphere) | 支持距离计算和范围查询,实现基于位置的精准推荐。 |
DDS索引的运行原理
DDS索引的运行原理是一个多组件协同工作的过程,其核心目标是实现海量文档数据的高效查询。
- 核心存储与数据结构层
- B+树索引结构:这是DDS索引的静态数据结构基础。当您创建索引时,存储引擎会对指定字段的值进行排序,构建一棵B+树。其特点是非叶子节点只存储键值用于导航,所有真正的数据指针(指向文档磁盘位置的指针)都存储在叶子节点,且叶子节点间通过指针相连。这种结构非常适合于范围查询和排序操作,因为只需遍历叶子节点链表即可。
- 分布式架构层
- 分片集群(Sharding):
- 索引分布:在分片集群中,索引并非一个全局单一结构。每个分片(Shard)只存储并维护自己分片内数据的索引。例如,一个基于userId哈希分片的集合,其索引也是按分片分布的。
- 查询路由:当查询到来时,路由器(Mongos) 会先分析查询条件。如果查询包含分片键(如userId),则可以直接将请求路由到特定的分片,实现定向查询。否则,会发起散射-聚集查询,将查询发往所有分片,再汇总结果。
- 副本集(Replica Set):
- 高可用性:索引在副本集中会从主节点自动同步到所有从节点。这确保了即使主节点故障,从节点提升为新主后,索引依然可用,保证了查询性能的连续性。
- 读写分离:可以将读请求分发到从节点,利用从节点的索引来分担主节点的查询压力。
- 分片集群(Sharding):
- 生命周期管理层
- TTL索引机制:这是一种特殊的单字段索引,用于自动清理过期数据。创建TTL索引时需指定一个过期时间(expireAfterSeconds)。DDS会启动一个后台线程,定期扫描该索引字段的值,并与当前时间比较。一旦发现文档的生存时间超过设定值,则会自动删除该文档,并清理对应的索引条目。这常用于会话管理、日志存储等场景。
DDS索引的分类
| 分类 | 说明 | 适用场景 |
|---|---|---|
| 默认索引 | 自动在_id字段创建唯一索引,不可删除。 | 防止重复文档插入。 |
| 单字段索引 | 对单个字段创建升序/降序索引,如db.collection.createIndex({field:1})。 | 简单查询(如{field: "value"})。 |
| 复合索引 | 多字段组合索引,如{userid:1, score:-1},遵循最左前缀原则。 | 多条件查询(如{userid: "A", score: >80})。 |
| 多键索引 | 自动为数组字段的每个元素创建索引项,支持$in等数组查询。 | 标签分类(如{hobbies: ["reading", "sports"]})。 |
| TTL索引 | 基于时间字段自动删除过期文档,如日志清理。 | 临时数据存储(如会话缓存)。 |
| 部分索引 | 仅索引符合条件的文档,如{partialFilterExpression: {age: {$gt: 18}}}。 | 过滤数据(如仅索引活跃用户)。 |
| 稀疏索引 | 仅索引包含目标字段的文档,适用于字段缺失率高的场景。 | 可选字段(如{optionalField: 1})。 |
| 通配符索引 | 支持动态字段匹配,如{** : 1},适用于嵌套结构。 | 动态JSON字段(如{user.profile.name: 1})。 |
DDS索引和MongoDB索引的区别
DDS索引和MongoDB索引虽然都基于相同的B+树和WiredTiger存储引擎技术,但它们在服务模式、运维特性和企业级功能上有显著差异。下面简要对比表4。