新集合索引内存驻留容量需分四步推算:先用db.collection.stats获取真实storagesize;再按索引类型(单字段0.65、复合0.82、文本/地理1.1~1.4)乘系数,数组或ttl索引额外×1.25;然后依查询命中率(<0.15→×0.4,>0.6→×0.95,批处理→×0.15)加权;最后校验wiredtiger cache余量是否≥结果×1.3,否则需调大缓存或删索引。

要为新集合预估索引在内存中实际驻留所需的容量,不能直接用磁盘索引大小除以物理内存比例,必须结合WiredTiger缓存机制、访问模式和索引结构特性分步推算。
第一步:获取新集合的索引体积基准值
在目标数据库中创建测试索引后,立即运行 db.collection.stats({indexDetails: true, scale: 1048576})。重点提取 indexDetails 中每个索引的 storageSize 字段(单位MB),不是 totalIndexSize——后者是全库总和且含padding冗余,会高估20%以上。
这一步操作起来很简单,直接把命令粘贴进mongosh就行。注意:必须在索引创建完成且有真实写入后再执行,刚建完空索引时 storageSize 可能为0或极小值,不具备参考性。
第二步:按索引类型修正内存驻留系数
不同索引类型在WiredTiger cache中实际占用与磁盘体积比差异极大:
方法一:单字段升序/降序索引 → 系数取 【0.65】。B-tree节点高度低、分支因子大,热数据页集中,常驻内存效率高。
方法二:复合索引(≥3字段)→ 系数取 【0.82】。字段组合导致key膨胀,B-tree层级加深,相同查询频次下需加载更多中间页。
方法三:文本索引或2dsphere地理索引 → 系数取 【1.1~1.4】。倒排表或R-tree结构天然稀疏,cache中碎片率高,实际驻留体积常超磁盘存储量。
若索引含TTL或部分字段为数组(multikey),必须在对应系数基础上再乘1.25——数组元素会强制分裂索引条目,显著增加cache压力。
第三步:叠加工作集热度权重
第一步得出的修正后体积只是理论上限,真实内存占用由查询频率决定:
① 执行 db.collection.explain("executionStats").find({yourQuery}),检查返回中的 executionStats.nReturned 与 executionStats.totalKeysExamined 比值。比值<0.3说明该索引扫描低效,实际进入cache的键范围远小于索引总大小。
② 若查询命中率长期低于0.15,将第二步结果乘以0.4;若稳定高于0.6,乘以0.95——WiredTiger会优先保留高命中率索引页。
③ 对于仅用于凌晨批处理的索引,无论体积多小,都按 【0.15】 权重计算,因其白天几乎不触发cache加载。
第四步:校验WiredTiger cache剩余空间
连接到mongod实例,运行 db.serverStatus().wiredTiger.cache["bytes currently in the cache"] 获取当前cache已用字节数。
用配置的 wiredTigerCacheSizeGB 值(默认50%物理RAM,上限1GB)换算成字节,减去当前已用量,得到可用余量。
若第四步余量 < 第三步最终结果 × 1.3,则必须调大 wiredTigerCacheSizeGB 或删减非核心索引——【WiredTiger不会主动淘汰冷索引页来腾出空间给新索引,而是直接拒绝加载】。











