我第一次尝试使用 MongoDB C# 驱动程序,我发现了一些奇怪的性能结果。 当我使用 ordering 和 .Take(1) 查询包含 300 万条记录的集合时,响应几乎是即时的(3 毫秒)。但是当我 .Take(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();
最佳答案
MongoDB C# Driver会将 string.Contains 方法转换为正则表达式。所以 c.SearchStringContains("abc")
将被翻译成:
{ SearchString : /abc/ }
但是,MongoDB 只能在“开头为”正则表达式上使用索引。引用自 documentation :
$regex can only use an index efficiently when the regular expression has an anchor for the beginning (i.e. ^) of a string and is a case-sensitive match. Additionally, while /^a/, /^a./, and /^a.$/ match equivalent strings, they have different performance characteristics. All of these expressions use an index if an appropriate index exists; however, /^a./, and /^a.$/ are slower. /^a/ can stop scanning after matching the prefix.
我怀疑如果你使用 explain command在您的查询中,您会看到包含 SearchString
字段的索引没有得到有效使用。
我相信 Take(1)
比 Take(2)
快的原因可能是您的 SearchString
index 仅用于查询的排序部分,第一个匹配出现在 B-Tree 遍历的早期。第二次出现很可能在 B-Tree 遍历中发生得更晚,导致更高的 nscan
(服务器扫描以查找结果的文档数)。
要解决此问题并能够使用索引,我建议使用 keyword search approach ;或者如果你有 v2.4+,你可以尝试 text search功能。
关于c# - MongoDB C# 驱动程序获取速度快(1) 但速度慢(2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18467208/