db.users.find({ nickname: /^张/ }).explain();
db.users.createIndex({ nickname: 1 });
按昵称做模糊搜索要八秒,explain 里 stage 是 COLLSCAN,索引明明建在 nickname 上却完全没用。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,正则写成不带锚点的包含匹配,或者加了 i 选项,索引只支持左锚定且大小写固定的前缀匹配,改法很小但效果差很多。
「MongoDB 正则索引失效」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改完隔一天再看一次,当场正常不代表能稳住。
测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
处理上按这个顺序:把正则改成 ^ 开头的左锚定前缀匹配再测一次;需要忽略大小写就另存一个规范化的小写字段;再用 explain 确认已经从全表扫描变成索引扫描。
改完只确认一件事:explain 显示走索引,模糊搜索从八秒降到几十毫秒以内。
