我在2012年3月13日安装了最新的MongoDB 64位数据库和官方C#驱动程序。我使用游标获得了一些意想不到的性能结果。
以下代码将在我的Core 2 Duo 2 GHz笔记本电脑上以大约26.8 k / sec的速度检索和循环500,000条记录:
var query = Query.EQ("_H._t", "Car");
var cursor = mc.FindAs<RoctObj>(query);
double priceTot = 0d;
foreach (RoctObj item in cursor)
{
Car car = (Car)item._H;
priceTot += car.Price;
}
这似乎很合理。接下来,我调整了查询,以便只返回721个结果。与使用以下代码替换foreach段相比,代码执行时间超过1.1秒。
long i = cursor.Count();
考虑到第一个例子的速度,721个记录应该只需要几分之一秒来迭代。我知道还有一些其他开销,但它们应该是那么糟糕。我不明白为什么我会得到+1.1秒。
有什么想法吗?
修改
这是备用查询。请注意,查询时间不是问题。这是迭代时间。
var query = Query.And(
Query.LTE("_H.Price", BsonDouble.Create(80000d)).GTE(BsonDouble.Create(40000d)),
Query.LTE("_H.Cylinders", BsonDouble.Create(8d)).GTE(BsonDouble.Create(4d)),
Query.LTE("_H.Capacity", BsonDouble.Create(3000d)).GTE(BsonDouble.Create(2000d)),
Query.LTE("_H.TopSpeed", BsonDouble.Create(200d)).GTE(BsonDouble.Create(100d))
);
答案 0 :(得分:3)
调用cursor.Count()不会将数据从服务器传输到您的应用程序。它向服务器发送一个命令,并在服务器上执行计数,只有一个小数据包从服务器返回,包含计数的数字结果。
不确定为什么迭代文档所花费的时间比简单计数要长得多。一个原因可能是服务器只能使用索引计算计数,但是当您实际迭代文档时,如果服务器尚未被分页到内存中,则必须从磁盘中获取每个文档。
它不太可能成为C#驱动程序反序列化代码中的任何瓶颈,因为它非常快。
如果您可以提供演示观察到的行为的示例程序,我将很乐意尝试重现您的结果。
答案 1 :(得分:1)
MongoDB不会立即返回所有结果,它会返回一个游标,一次一条记录从数据库中读取数据,因为您的应用程序要求它(即在迭代期间),这可能是它变慢的原因。 / p>
运行count()
只会返回找到但没有数据的匹配数量。