具有索引字段的MongoDB正则表达式

时间:2011-11-12 19:51:10

标签: regex mongodb indexing mongodb-indexes

我正在使用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" : {

        }
}

显然,使用没有正则表达式的索引搜索字段的速度要快得多(即使用常量字段搜索文档),但我真的对这种行为的原因感兴趣。

1 个答案:

答案 0 :(得分:13)

这里的性能差异的原因很可能是,在启用索引的情况下,您的查询必须遍历索引(加载到内存中),然后加载匹配的文档以便返回到内存中。由于您未使用前缀查询,因此将根据正则表达式扫描和测试索引中的所有值。效率不高。

当您删除索引时,您只是在进行表扫描并在那里匹配正则表达式 - 基本上您从第一个略微简化了一些事情。

如果索引版本是covered index query,您可以更快地制作索引版本,如果这是一个复合索引,并且您需要将其与另一个字段的条件相结合,它也可能更快。

当你使用前缀查询时,并不是它只使用索引,而是你有效地使用索引,这是关键,因此你会看到真正的性能提升。