我第一次玩MongoDB C#驱动程序,我发现性能有些奇怪。 当我查询一个有300万条记录并且订购的集合时。(1)响应几乎是瞬间的(3毫秒)。但是当我。在同一个查询中采取(2)它需要10秒。 正确的索引就位,它是一个非常简单的测试数据集合。
MongoClient client = new MongoClient();
MongoServer server = client.GetServer();
var database = server.GetDatabase("db_name");
var collection = database.GetCollection<MyType>("collection_name");
var query = from c in collection.AsQueryable<MyType>()
where c.SearchString.Contains(searchString)
orderby c.SearchString
select c.SearchString;
List<string> results = query.Take(2).ToList();
答案 0 :(得分:4)
MongoDB C# Driver会将字符串.Contains方法转换为正则表达式。因此c.SearchStringContains("abc")
将被翻译为:
{ SearchString : /abc/ }
但是,MongoDB只能在“start with”正则表达式上使用索引。引用documentation:
$ regex只能在正则表达式时有效地使用索引 有一个锚的开头(即^)的字符串,是一个 区分大小写的匹配。另外,当/ ^ a /,/^a。 /和/^a.$/ 匹配等效字符串,它们具有不同的性能 特点。所有这些表达式都使用索引 适当的指数存在;但是,/ ^ a。 /,和/^a。 $ /更慢。 / ^ a /可以在匹配前缀后停止扫描。
我怀疑如果您在查询中使用explain command,您会发现包含SearchString
字段的索引未得到有效使用。
我认为Take(1)
比Take(2)
更快的原因可能是您的SearchString
索引仅用于查询的排序部分,而第一个匹配发生在B-Tree步行的早期。第二次出现可能会在B-Tree漫游中发生得更晚,导致nscan
更高(服务器扫描查找结果的文档数量)。
要解决此问题并能够使用索引,我建议使用keyword search approach;或者,如果你有v2.4 +,你可以尝试text search功能。