MongoDB C#游标性能问题

时间:2012-03-13 16:31:51

标签: performance mongodb cursor mongodb-.net-driver

我在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))
        );

2 个答案:

答案 0 :(得分:3)

调用cursor.Count()不会将数据从服务器传输到您的应用程序。它向服务器发送一个命令,并在服务器上执行计数,只有一个小数据包从服务器返回,包含计数的数字结果。

不确定为什么迭代文档所花费的时间比简单计数要长得多。一个原因可能是服务器只能使用索引计算计数,但是当您实际迭代文档时,如果服务器尚未被分页到内存中,则必须从磁盘中获取每个文档。

它不太可能成为C#驱动程序反序列化代码中的任何瓶颈,因为它非常快。

如果您可以提供演示观察到的行为的示例程序,我将很乐意尝试重现您的结果。

答案 1 :(得分:1)

MongoDB不会立即返回所有结果,它会返回一个游标,一次一条记录从数据库中读取数据,因为您的应用程序要求它(即在迭代期间),这可能是它变慢的原因。 / p>

运行count()只会返回找到但没有数据的匹配数量。