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

查询计划竞选:候选计划各试跑多少文档

实测候选计划的试跑:每个候选计划最多取 101 条结果或 10000 次 works,同样的 works 里谁返回得多谁赢(b_1 返回 101 条,a_1 只返回 1 条);参数调成 10 后试跑缩短;SORT 阻塞,没有阻塞排序的计划更占便宜;结果很少时几次 works 就结束;最后验证选中的 b_1 在完整执行里确实最快。

MongoDB 查询优化器 计划竞选 allPlansExecution 计划试跑 真实验证 动画演示
MongoDB 2026-10-12

计划缓存:什么时候会失效重选

实测计划缓存:第一次执行产生 inactive 条目、第二次确认后变 active;同形状不同常量共用一个条目;换常量让缓存计划变慢(11 works 变成至少 110 works)时 profiler 记录 replanned 并重选;创建或隐藏索引会清空缓存;条目里的字段与手动清理。

MongoDB 计划缓存 planCache replan planCacheStats 真实验证 动画演示
MongoDB 2026-10-12

hint:强制索引什么时候反而更慢

实测 hint:优化器自己选的 user_1 只要 0.2 ms,hint 到 status_1 要 29 ms、全表 46 ms;键模式与索引名都可以,不存在的索引报错;hint 的计划不进计划缓存;用错 hint 让按 user 的查询慢 563 倍;aggregate、count、update 里的 hint 写法。

MongoDB hint 强制索引 查询计划 性能 真实验证 动画演示
MongoDB 2026-10-12

内存排序的 100MB 限制与 allowDiskUse

实测内存排序的 100 MiB 限制:9.0.2 默认 allowDiskUseByDefault 为 true,关掉之后 147.5 MB 的无索引排序报 code 292;allowDiskUse 时 SORT 阶段溢出 2 次共 155,400,000 字节仍成功;sort + limit 是 top-k 不会超限;有索引则没有 SORT 阶段。

MongoDB 排序 100MB内存限制 allowDiskUse SORT 真实验证 动画演示
MongoDB 2026-10-12

$or:每个分支各自走哪个索引

实测 $or 如何用索引:每个分支都有索引时各走各的并由 OR 阶段去重;一个分支没有索引整个 $or 全表扫描(240 对 200,000 个文档);外层条件要有对应的复合索引才分配进每个分支;$or 加 sort 在每个分支都能有序时用 SORT_MERGE;同一字段的 $or 与 $in 计划相同。

MongoDB $or 索引 SORT_MERGE explain 真实验证 动画演示
MongoDB 2026-10-12

正则查询:什么写法能用上前缀索引

实测正则能否用上前缀索引:/^abc/ 收窄成 ["abc", "abd") 只检查 17 个键;不锚定的 /abc/、/^abc/i、/^.*abc/、带分支的 /^(abc|abd)/ 扫整个索引 300,006 个键(约 100 ms);小写副本字段、$in 里分开写正则是可行办法;正则不使用 collation。

MongoDB 正则 前缀 索引 regex 真实验证 动画演示
MongoDB 2026-10-12

文本索引:$text 的分词与打分

实测文本索引:英文词干把 jumped、foxes 归一到 jump、fox;停用词(the)不进索引;大小写与重音默认不敏感;多词按 OR、引号是短语、减号排除;textScore 打分与 title 权重 10 的效果(3.55 升到 15.55);一个集合只能有一个文本索引。

MongoDB 文本索引 $text 分词 词干 textScore 真实验证 动画演示
MongoDB 2026-10-12

2dsphere 地理索引:$near 怎么查

实测 2dsphere 地理索引:5 万个点每个一个索引条目;$near 按距离排序,与 Python haversine 暴力计算的 272 个结果顺序完全一致;GEO_NEAR_2DSPHERE 逐圈扩展搜索(452 个键);多边形生成 5~20 个索引键;经纬度写反的两种后果。

MongoDB 2dsphere 地理索引 $near $geoNear GeoJSON 真实验证 动画演示
MongoDB 2026-10-12

哈希索引:能做等值,不能做范围

实测哈希索引:存值的 64 位哈希,相邻值哈希后差很远;只能做等值,范围查询要扫整个索引(200,000 个键,142 ms 对普通索引的 2 ms),排序也不行;不支持 unique、数组,复合索引最多一个哈希字段;浮点数会截断成整数再哈希;连续整数哈希后均匀分散。

MongoDB 哈希索引 hashed 分片 等值查询 真实验证 动画演示
MongoDB 2026-10-12

通配符索引:什么场景值得用

实测通配符索引:一个 attrs.$** 覆盖 50 个动态键名(300,000 条索引),查询检查 291 个文档而不是全表 100,000 个;两个条件同时出现只能用一个字段;能做同字段的范围加排序和 $exists: true,不能做 $ne;写入慢 1.9 倍;不支持 unique,复合通配符的要求。

MongoDB 通配符索引 wildcard attrs 动态字段 真实验证 动画演示
MongoDB 2026-10-12

建索引期间读写会被阻塞吗

实测建索引期间读写会不会被阻塞:800 万个文档上建索引 7.9 s,并发线程的读写 p99 几乎不变且没有错误;currentOp 显示 scanning collection 与 inserting keys 的进度;期间插入的文档也被建进索引;唯一索引期间并发插入的重复值不会被拒绝,建索引最后以 E11000 失败;drop 会中止构建。

MongoDB 建索引 index build 阻塞 currentOp 真实验证 动画演示
MongoDB 2026-10-12

隐藏索引:不删索引也能评估删掉的影响

实测隐藏索引:hideIndex 之后优化器不再考虑它(0.2 ms 变成 28 ms 全表扫描),unhideIndex 立刻恢复;隐藏的索引仍然被维护(隐藏期间写入的数据取消隐藏后立即可查),唯一与 TTL 约束照常工作,hint 视其为不存在,$indexStats 不再计数。

MongoDB 隐藏索引 hideIndex 索引 计划器 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号