系列八、MongoDB索引

MongoDB中的索引能提升查询效率,避免全集合扫描。可以按字段创建升序或降序索引,甚至设置过期时间。通过`createIndex`创建,`getIndexes`查看,`dropIndexes`删除索引。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

        索引通常能够极大地提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件,并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量数据时,查询可能要花费几十秒甚至几分钟,这对网站的性能是非常致命的,索引是一种特殊的数据结构,存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或者多列的值进行排序的一种结构。

二、原理

从根本上来说,MongoDB中的索引与其他数据库系统中的索引类似。MongoDB在集合层面上定义了索引,并支持对MongoDB集合中的任何字段或者文档的子字段进行索引。

三、索引操作

3.1、创建索引

# 语法
db.集合名称.createIndex(keys,options)
db.集合名称.createIndex({"title":1,"description":-1})

说明:语法中的key值为你要创建的索引字段,1:升序创建索引、-1:降序创建索引

createIndex可接收的参数如下:

3.1.1、为user集合的name字段创建升序索引

# 案例:为user集合的name字段创建升序索引
db.user.createIndex({name:1})

3.1.2、为user集合的name字段创建带有过期时间的索引

 3.1.3、创建复合索引

db.user.createIndex({name:1,age:-1},{name:'idx_name_age'})

 3.2、查看索引

# 语法
db.集合名称.getIndexes()

3.2.1、查看user集合中的所有索引 

# 案例:查询user集合中所有的索引
db.user.getIndexes()

3.2.2、查看集合索引的大小

# 语法:
db.集合名称.totalIndexSize()

db.user.totalIndexSize()

 3.3、删除索引

# 语法
# 删除所有索引(不包含_id索引)
db.集合名称.dropIndexes()

3.3.1、删除所有索引 

# 案例:删除user集合中所有的索引
db.user.dropIndexes()

 3.3.2、删除指定索引

# 语法:
db.集合名称.dropIndex("索引名称")

# 案例:删除user集合中name为idx_name的索引
db.user.dropIndex('idx_name')

### MongoDB索引优化的最佳实践和方法 #### 一、索引的基本概念与作用 MongoDB中的索引是一种特殊的数据结构,用于加速查询操作。它通过减少扫描文档的数量来提高查询效率[^1]。如果没有合适的索引支持,MongoDB会执行全表扫描(Full Collection Scan),这可能导致严重的性能问题。 #### 二、索引的创建与管理 在实际应用中,可以通过以下方式创建索引: - **单字段索引**:适用于基于单一字段的查询条件。 - **复合索引**:当查询涉及多个字段时,可以创建复合索引来覆盖这些字段组合。 - **TTL索引**:对于需要自动过期删除的数据集合非常有用。 - **全文索引**:适合于文本搜索场景。 以下是创建复合索引的一个例子: ```javascript db.collection.createIndex({ fieldA: 1, fieldB: -1 }); ``` 此命令会在 `fieldA` 和 `fieldB` 上创建一个升序降序混合的复合索引。 #### 三、索引优化的关键技术 为了实现更高效的查询处理,可以从以下几个方面入手: ##### 1. 查询计划分析 利用 `explain()` 函数可以帮助开发者理解当前查询是如何被执行的以及哪些索引被使用到了。如果发现有未命中索引的情况,则可能需要重新设计或者新增加相应的索引[^2]。 示例代码如下所示: ```javascript db.orders.find({ status: "A", amount: { $gt: 100 } }).sort({ date: -1 }).explain("executionStats"); ``` ##### 2. 避免不必要的索引 虽然索引能够加快读取速度,但是过多无意义的索引反而会影响写入性能,因为每次更新都需要同步维护各个相关联的索引条目。因此,在规划阶段就应该仔细权衡利弊关系[^3]。 ##### 3. 使用覆盖查询(Covered Query) 所谓覆盖查询是指整个查询过程完全依赖某个已存在的索引来完成而无需访问原始记录本身即可返回所需的结果集。这样的做法显著降低了I/O消耗从而提升了整体表现水平。 #### 四、实战案例分享 假设存在这样一个业务需求——统计过去一年内每种商品类别下的销售总额排名前五名的品牌名单及其对应的销售额明细信息。针对该类复杂报表型任务通常采用管道式聚合框架配合恰当设置好的辅助性指标共同协作达成目标效果。 具体步骤分解如下: 1. 利用 `$match` 过滤掉不符合时间范围内的订单项; 2. 接着借助 `$unwind` 展开数组形式存储的商品详情列表以便单独计算各单品贡献度; 3. 再经过一系列分组累积运算得出最终汇总数值; 4. 最后再按照指定维度排序截取出限定数量结果呈现给前端调用方消费展示出来。 值得注意的是在整个链路当中每一个环节都应当尽可能早地引入有效的筛选逻辑以缩小后续参与加工的基础规模进而达到全局提速的目的。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值