2014-02-27 55 views
0

这是mongodb中的一个简单搜索的解释,它花费超过2.4秒和更多来检索数据。如果我添加索引(搜索参数),它需要超过5秒。如何提高mongo简单搜索查询的性能

查询

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" 
    } 

回答

0

没有任何理由,因为你使用正则表达式对这个搜索PARAMS添加索引。只有当regExp在开始时有一个锚点时,索引才能改善使用regExp的查找。

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

documentation

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

0

没有很多事情可以做。你有五十万个元素,你正在全部扫描它们。毫不奇怪,这需要时间。此外,你的搜索是基于正则表达式,它可以在字符串中的任何地方。所以在这种情况下索引不能帮助你。

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

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

+0

我首先使用数组来存储名称,就像您所说的那样,并为该数组添加索引,但发现它非常昂贵。这个搜索花费了3-10分钟,所以我将它改为单列,这可以减少时间,但这仍然只是我的测试数据。生产将有更多的数据..请帮助一些解决方案 – deepu

+0

你能从数组解决方案和你的文档中的相关示例中显示你的解释吗? –

1

预定为2.6版本的MongoDb是full text search功能。如果启用,它可作为当前版本的开发预览版提供。

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

如果您可以锚定正则表达式,这意味着它将更改为“字符串开头”而不是“字符串包含”,如果您规范化字符串以便忽略所有字符大小写,并且实现那场比赛将仍然是确切的。例如,a不是á,需要特别处理。

对于这种类型的查询,Mongo对于生产使用的支持确实有限。您可能会发现全文搜索功能也不适合。如果这个查询很重要,我会建议考虑其他搜索机制。例如,可能看着像Elastic Search这样的东西。

+0

在mongodb中使用全文搜索功能是一种可靠的方法或解决方案..?我发现不建议在生产中使用它。 – deepu

+0

2.6现在正在发布候选版本。我建议你可能想考虑非Mongo解决方案。 – WiredPrairie