我目前开发的系统使用 MongoDB 2.4.4
我有一组用户。
有一个组合索引:{ "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
我也尝试过使用单个索引,但没有提高性能
该系统包含 400.000 条测试记录。
查询(来自 org.springframework.data.mongodb.core.query.Query 的 Java 调试):
{ "LASTNAME" : { "$regex" : "^Schm"}},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 ,"LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
在 16 毫秒内执行。这太棒了。
此查询未显示在 MongoDB 控制台中(此处没有要发布的调试信息)。
但是,我喜欢搜索不仅要以开头,而且应该不区分大小写。
查询:
{ "LASTNAME" : { "$regex" : "^Schm" , "$options" : "i"}},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 , "LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
在 897 毫秒内执行。这是不可接受的慢。
Mongo 控制台显示:
query: { query: { LASTNAME: /^Schm/i },
orderby: { LASTNAME: 1, FIRSTNAME: 1, EMAIL: 1, CITY:1, STATUS: 1 }
} cursorid:1252405545564528 ntoreturn:25 ntoskip:0 nscanned:297651
keyUpdates:0 numYields: 1 locks(micros) r:1391715 nreturned:25 reslen:4422 897ms
可以看出。指向索引问题的不是 scanAndOrder 问题。
然后我尝试以适合大多数情况的下一种方式解决它(从用户插入,小写和大写),但这也更慢。我的期望是,它执行的时间是第一个查询的三次。
查询:
{ "$or" : [ { "LASTNAME" : { "$regex" : "^Schm"}} , { "LASTNAME" : { "$regex" : "^schm"}} , { "LASTNAME" : { "$regex" : "^SCHM"}}]},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 , "LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
在 1300 毫秒内执行。没什么好说的。
MongoDB 控制台:
query: { query: { $or: [ { LASTNAME: /^Schm/ }, { LASTNAME: /^schm/ }, { LASTNAME: /^SCHM/ } ] },
orderby: { LASTNAME: 1, FIRSTNAME: 1, EMAIL: 1, CITY: 1, STATUS: 1 }
} cursorid:43560166842085 ntoreturn:25 ntoskip:0 nscanned:297651
keyUpdates:0 numYields: 1 locks(micros) r:1531168 nreturned:25 reslen:4422 1300ms
那么,我怎样才能搜索不区分大小写,几乎有第一次搜索的速度呢?最大 150 毫秒!