如何提高mongo简单搜索查询的性能

时间:2014-02-27 07:54:32

标签: mongodb

这是对mongodb中简单搜索的解释,它需要超过2.4秒甚至更长时间来检索数据。如果我添加索引(搜索参数),则需要超过5秒。

查询

    db.CX_EMPLOYEES.find({ "$or" : [{ "AML_FULLNAME" : /RAJ/ }, 
{ "AML_FULLALIAS" : /RAJ/ }] })

解释

 {
        "cursor" : "BasicCursor",
        "isMultiKey" : false,
        "n" : 79,
        "nscannedObjects" : 504570,
        "nscanned" : 504570,
        "nscannedObjectsAllPlans" : 504570,
        "nscannedAllPlans" : 504570,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 2423,
        "indexBounds" : {},
        "server" : "SERVER:27017"
    }

3 个答案:

答案 0 :(得分:1)

计划使用2.6版本的MongoDb是full text search功能。如果启用,它可作为当前版本中的开发预览。

鉴于您的查询的性质,它可能是仅使用MongoDb可能有效的唯一选项。当您尝试根据您提供的正则表达式执行“字符串包含”搜索时,根据您的集合大小,执行搜索以匹配多个字段上的字符串的性能将非常糟糕。虽然这是一个简单的概念查询,但转换为高效查询非常困难。 Mongo需要扫描每个文档以进行匹配。分开单词并没有帮助,因为Mongo仍然需要扫描每个文档。

如果您可以锚定正则表达式,这意味着它将更改为“字符串以”开头而不是“字符串包含”,如果您对字符串进行规范化以便忽略所有字符大小写,并且意识到这一点,那么性能应该是合理的比赛将是准确的。例如,a不是á,需要特别处理。

Mongo对此类查询的支持实际上仅限于生产用途。您可能会发现全文搜索功能也不合适。如果这个查询很重要,我建议考虑其他搜索机制。例如,可能会查看Elastic Search之类的内容。

答案 1 :(得分:0)

由于您使用regExp,因此没有任何理由在此搜索参数上添加索引。只有当regExp具有开头的锚时,索引才能使用regExp改进查找。

db.CX_EMPLOYEES.find({ "$or" : [{ "AML_FULLNAME" : /^RAJ/ }, { "AML_FULLALIAS" : /^RAJ/ }] })

来自documentation

  

$ regex只能在正则表达式具有字符串开头(即^)的锚点时有效地使用索引,并且是区分大小写的匹配。另外,当/ ^ a /,/^a。* /和/^a.*$/匹配等效字符串时,它们具有不同的性能特征。如果存在适当的索引,则所有这些表达式都使用索引;但是,/^a。* /和/^a.*$/比较慢。 / ^ a /可以在匹配前缀后停止扫描。

答案 2 :(得分:0)

你可以做很多事情。你有一半的元素,你正在对所有元素进行全面扫描。这需要时间,这并不奇怪。此外,您的搜索基于正则表达式,可以在字符串中的任何位置。所以索引在这种情况下无法帮助你。

如果您的搜索基于单词,则可以尝试从字符串创建数组。例如,字符串'Salvador Domingo Dali'将转换为['Salvador', 'Domingo', 'Dali']。如果您要在此数组上添加索引并尝试查找'Dali',则搜索将利用此索引。

P.S。数据库和索引不是灵丹妙药。有时你需要一个更好的逻辑来处理大量数据。