我正在使用MongoDB创建我的第一个应用程序。 创建了一个字段的索引,并尝试使用$ regex param在shell中启动查找查询
> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
"cursor" : "BtreeCursor A_1 multi",
"nscanned" : 500001,
"nscannedObjects" : 10,
"n" : 10,
"millis" : 956,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"A" : [
[
"",
{
}
],
[
/BLABLA!25500[0-9]/,
/BLABLA!25500[0-9]/
]
]
}
}
这很奇怪,因为当我启动相同的查询但没有收集索引时,性能要好得多。
> db.foo.find({A:{$regex:'BLABLA!25500[0-9]'}}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 500002,
"nscannedObjects" : 500002,
"n" : 10,
"millis" : 531,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
显然,使用没有正则表达式的索引搜索字段的速度要快得多(即使用常量字段搜索文档),但我真的对这种行为的原因感兴趣。
答案 0 :(得分:13)
这里的性能差异的原因很可能是,在启用索引的情况下,您的查询必须遍历索引(加载到内存中),然后加载匹配的文档以便返回到内存中。由于您未使用前缀查询,因此将根据正则表达式扫描和测试索引中的所有值。效率不高。
当您删除索引时,您只是在进行表扫描并在那里匹配正则表达式 - 基本上您从第一个略微简化了一些事情。
如果索引版本是covered index query,您可以更快地制作索引版本,如果这是一个复合索引,并且您需要将其与另一个字段的条件相结合,它也可能更快。
当你使用前缀查询时,并不是它只使用索引,而是你有效地使用索引,这是关键,因此你会看到真正的性能提升。