完整教程:【MongoDB实战】6.3 索引优化实战:慢查询解决(补充)

6.3 索引优化实战:慢查询解决

慢查询是MongoDB性能瓶颈的核心来源之一,其本质是查询未有效利用索引,导致全表扫描(COLLSCAN)。

  • 本节通过实战代码+执行计划分析+索引优化的完整流程,讲解慢查询的识别、优化及索引使用的核心准则。

6.3.1 识别慢查询:explain()方法深度解析

核心概念

  • 慢查询定义:MongoDB默认将执行时间超过100ms的查询标记为慢查询(可通过setParameter修改阈值:db.adminCommand({setParameter:1, slowMS:200}))。

  • explain()作用:分析查询执行计划,定位慢查询瓶颈(是否走索引、扫描文档数、执行时间等)。

  • explain()三种模式:

模式说明适用场景
queryPlanner(默认)仅返回优化器选择的查询计划(不执行查询)快速查看索引是否被选中
executionStats执行查询并返回详细执行统计分析慢查询的真实性能指标
allPlansExecution返回所有候选计划的执行统计复杂查询的计划对比

实操步骤1:准备测试数据集

以用户数据为例,插入10万条测试数据模拟真实场景(Mongo Shell/ mongosh 执行):

// 1. 切换到测试数据库
use test_db;
// 2. 清空原有数据(测试用)
db.users.drop();
// 3. 生成10万条用户测试数据
let users = [];
for (let i = 0; i < 1000000; i++) {

users.push({

username: `user_${i}`,
age: Math.floor(Math.random() * 50) + 18, // 年龄18-68岁
city: ["北京", "上海", "广州", "深圳", "杭州"][Math.floor(Math.random() * 5)], // 随机城市
register_time: new Date(Date.now() - Math.floor(Math.random() * 365 * 24 * 3600 * 1000)), // 近一年注册
is_vip: Math.random() > 0.7, // 30% VIP用户
phone: `13${Math.floor(Math.random() * 900000000) + 100000000}` // 随机手机号
});
}
// 4. 批量插入数据(MongoDB默认单次insertMany上限16MB,该数据量无压力)
db.users.insertMany(users);
print(`测试数据插入完成,总数:${db.users.countDocuments()} 条`);

实操步骤2:执行慢查询并分析执行计划

示例场景:查询「北京市的VIP用户,年龄大于30岁」,未加索引时分析执行计划:

// 简化版:只显示关键指标
let query
posted @ 2026-01-17 13:02  clnchanpin  阅读(8)  评论(0)    收藏  举报