c# - MongoDB C# 驱动程序获取速度快(1) 但速度慢(2)

标签 c# performance linq mongodb

我第一次尝试使用 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/

相关文章:

c# - 在 DataTable 上使用 LINQ 的 .Any()

c# - 具有完整迁移支持的 .net Active Record ORM

java - 在 GWT 中使用模拟堆栈有多少开销?

performance - 迭代 Scripting.Dictionary/Collection 对象

c# - 没有任何html标签的元素的节点名称是什么?

c# - 问题: Failed to load viewstate

c# - Awesomium Winforms 在 VMWare 中不工作

c# - Blazor WebAssembly 应用程序/身份验证/注销导致 "There was an error trying to log you out: ' '"失败

c# - 根据条件在 C# 中合并两个列表

c++ - 在性能方面,使用 'nullptr' 还是仅使用 '0' 更快?