我正在使用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" : { } }
显然,使用没有正则表达式的索引搜索字段的速度要快得多(即使用常量字段搜索文档),但我真的对这种行为的原因感兴趣.
这里的性能差异的原因很可能是,在启用索引的情况下,您的查询必须遍历索引(加载到内存中),然后加载匹配的文档以便返回到内存中.由于您未使用前缀查询,因此将根据正则表达式扫描和测试索引中的所有值.不是很有效率.
当您删除索引时,您只是在进行表扫描并在那里匹配正则表达式 - 基本上您可以稍微简化第一个.
如果它是一个覆盖索引查询,您可以更快地使索引版本更快,如果这是一个复合索引并且您需要将它与另一个字段的条件组合,它也可能更快.
当您使用前缀查询时,并不是它只使用索引,而是有效地使用索引,这是关键,因此您可以看到真正的性能提升.