一聚教程网:一个值得你收藏的教程网站

热门教程

MongoDB 索引失效可能引发的生产故障有哪些?

时间:2026-07-13 09:30:51 编辑:袖梨 来源:一聚教程网

索引失效直接导致慢查询并拖垮MongoDB主库,表现为COLLSCAN、CPU和磁盘IO耗尽、高并发下查询卡死数秒;复合索引不满足最左前缀、字段顺序错误、类型不匹配或$regex前缀不固定均使其失效;低基数字段单独建索引反而加重写压力;必须通过explain验证索引真实生效。

索引失效直接引发慢查询,拖垮整个MongoDB主库

索引失效最直接的后果不是“查得慢一点”,而是大量查询退化为 COLLSCAN,在高并发下迅速耗尽磁盘IO和CPU。你看到的“服务器负载飙升”“Zabbix曲线剧烈抖动”,往往就是几十个未命中索引的查询同时扫全表导致的。尤其当业务存在“写完立刻查”逻辑(如插入订单后立即按状态拉取),主库会频繁锁住,出现 query 操作持续 4–5 秒甚至更久——这不是超时,是真实卡死。

复合索引不满足最左前缀,等于没建

比如你建了 {"orgCode": 1, "fixedStatus": 1, "_id": -1},但实际查询只传了 {"fixedStatus": {"$in": [1, 2]}}{"_id": ObjectId("...")},MongoDB根本不会用这个索引。它不会“挑着用”,只会降级为全表扫描。更隐蔽的是:字段顺序写反({"fixedStatus": 1, "orgCode": 1})、类型不一致(orgCode 是字符串,却传数字 350119)、或用了 $regex 前缀不固定,都会让整个复合索引失效。

低基数字段单独建索引,反而加重写压力

genderisDeleted 这类只有 2–3 个值的字段,单独建索引不仅无法加速查询(选择性太低),还会拖慢写入——每次插入/更新都要维护额外B+树节点。Spring Data 的 @Indexed 如果随手加在布尔字段上,上线后写吞吐量可能掉 20%+。真正该建索引的是高频、高选择性的组合,比如 {"tenantId": 1, "createdAt": -1},而不是单个状态位。

索引存在但没生效,explain 才是唯一真相

别信“我建了索引所以没问题”。必须对线上典型查询跑一遍 db.collection.explain("executionStats").find({...}),盯住三个字段:executionStages.stage 必须是 IXSCAN(不是 COLLSCAN);nReturned 应远小于 totalDocsExaminedexecutionTimeMillis 要稳定在毫秒级。如果 stageIXSCANtotalKeysExamined 接近总文档数,说明索引覆盖不全,得补投影字段或调整排序逻辑。

真正危险的不是没建索引,而是建了却不知道它没被用——这种“虚假安全感”会让问题在流量高峰时集中爆发。

热门栏目