知其然,知其所以然
MongoDB 2026-10-12

TTL 索引:过期文档什么时候才真正被删

实测 TTL 索引的过期时机:5 秒过期的文档要等到每 60 秒运行一次的 TTL 线程(实测 59.0 s 和 119.2 s)才被删;只有 BSON 日期(或日期数组)会过期;expireAfterSeconds 为 0 配合未来时间可让每个文档自己定过期时刻;collMod 在线改过期时间;20 万个过期文档一轮删完。

MongoDB TTL索引 过期 ttlMonitorSleepSecs collMod 真实验证 动画演示
MongoDB 2026-10-12

时序集合:bucket 文档长什么样

实测 9.0.2 的时序集合:底层 system.buckets 不能再直接访问,用 rawData 读到 3 个传感器各 400 个测量只占 3 个 bucket;bucket 文档按列存放、带 min/max/count;每个 bucket 最多 1000 个测量;合成数据占盘只有普通集合的 2%;默认索引与 update/delete 的限制。

MongoDB 时序集合 time-series bucket rawData 真实验证 动画演示
MongoDB 2026-10-12

视图:视图就是存下来的 pipeline

实测 MongoDB 视图:只是 system.views 里存下来的一条 pipeline,每次查询重新执行,底层数据一改视图立刻变化;视图没有自己的索引,过滤条件能前移到 $group 之前时走底层索引(150 个文档),在聚合结果上则全表扫描(3000 个);视图只读、深度上限 20、底层集合删除后查询为空、collMod 可以改 pipeline。

MongoDB 视图 view pipeline 索引 explain 真实验证 动画演示
MongoDB 2026-10-12

Schema 校验:validationLevel 与 validationAction 的区别

实测 Schema 校验:121 错误里 errInfo.details 逐条说明哪条规则没通过;validationAction 为 warn 时照样写入并在日志里记警告;validationLevel 的 strict 与 moderate 对不合法的老文档的区别;bypassDocumentValidation 与 off;$expr 校验器;insertMany 在 ordered 与 unordered 下的行为。

MongoDB Schema校验 jsonSchema validationLevel validationAction 真实验证 动画演示
MongoDB 2026-10-12

collation:大小写不敏感比较的代价

实测 collation:默认二进制比较,strength 2 忽略大小写、strength 1 连重音也忽略,numericOrdering 与 zh 拼音排序;collation 查询用不上不带 collation 的索引(全表检查 200,000 个文档),建同 collation 的索引后只检查 1 个;正则 /i 比全表 collation 更慢;集合级默认 collation 与索引变大 17%。

MongoDB collation 大小写 索引 排序 真实验证 动画演示
MongoDB 2026-10-12

explain 的三种模式:同一条查询看到的信息有什么不同

同一条查询在 explain 的三种模式下看到的信息:queryPlanner 只选计划不执行,executionStats 执行并给出键数、文档数和每个阶段的 works,allPlansExecution 再给出落选计划的试跑统计;update / delete 的 explain 不修改数据;aggregate 的 pipeline 被整个下推并成为覆盖查询。

MongoDB explain queryPlanner executionStats allPlansExecution 真实验证 动画演示
MongoDB 2026-10-12

复合索引字段顺序:等值、排序、范围(ESR)实测

实测复合索引字段顺序(等值、排序、范围):有 limit 20 时 E-S-R 只检查 195 个键最快,不 limit 时 E-S-R 要扫 60,001 个键而 E-R-S 只要 6000 个,反而 E-R-S 更快;优化器无 limit 时仍选了 E-S-R;范围换成等值后等值字段全放前面才是最优。

MongoDB 复合索引 ESR 排序 范围查询 explain 真实验证 动画演示
MongoDB 2026-10-12

覆盖查询:totalDocsExamined 怎么变成 0

实测覆盖查询:投影去掉 _id 且字段都在索引里时 totalDocsExamined 为 0;带 _id、取索引外字段、条件里有索引外字段、数组(multikey)字段都要 FETCH;把 _id 放进索引后带 _id 也能覆盖;count 与 $group 也能覆盖。

MongoDB 覆盖查询 索引 explain totalDocsExamined 真实验证 动画演示
MongoDB 2026-10-12

多键索引:数组字段会生成多少条索引条目

实测多键索引:数组每个元素一条索引条目(空数组、缺失、标量各 1 条,同一文档内重复元素去重),条目数和索引大小随数组长度线性增长(100 个元素时每个文档 884 字节),$elemMatch 比普通条件界限更紧,写入代价随元素数线性增长。

MongoDB 多键索引 multikey 数组 索引条目 真实验证 动画演示
MongoDB 2026-10-12

两个数组字段的复合索引为什么报错

实测两个数组字段的复合索引:同一文档里最多一个被索引字段是数组,两个都是数组时插入、更新报 171(cannot index parallel arrays),已有这种文档时建索引失败;同一数组的两个子字段不算并行;拆成单字段索引或展开成子文档数组两种办法的检查键数对比。

MongoDB 并行数组 复合索引 multikey CannotIndexParallelArrays 真实验证 动画演示
MongoDB 2026-10-12

部分索引与稀疏索引:哪些文档不进索引

实测稀疏索引与部分索引:稀疏索引收录字段存在的文档(显式 null 算存在),用 hint 或排序时会漏掉缺失的;部分索引只收录满足过滤条件的文档,体积小得多(24,576 对 155,648 字节),查询必须蕴含过滤条件才能用;软删除场景的唯一部分索引;过滤条件的限制($ne 不行,$or 可以)。

MongoDB 部分索引 稀疏索引 partialFilterExpression sparse 真实验证 动画演示
MongoDB 2026-10-12

唯一索引遇到 null 和缺失字段

实测唯一索引遇到 null 和缺失字段:缺失按 null 算,第二个缺失或 null 的文档就报 E11000;唯一加 sparse 允许任意多个缺失但显式 null 仍然冲突;唯一加部分索引(字符串 email)缺失和 null 都不限;复合索引逐字段按 null;已有重复数据时建索引失败及找重复的办法。

MongoDB 唯一索引 null 缺失字段 E11000 sparse 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号