2012-03-13 37 views
2

从2012年3月13日起,我安装了最新的MongoDB 64位数据库和官方C#驱动程序。我使用游标获得了一些意想不到的性能结果。MongoDB C#光标性能问题

以下约26.8 K /秒的代码将检索和环通500000条记录在我的Core 2 Duo 2 GHz的笔记本电脑:

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个结果。代码接管1.1秒长于执行如果在foreach段被替换为:

long i = cursor.Count(); 

鉴于第一实施例的速度,721个记录应该只需要几分之一秒进行迭代。我知道还有一些其他的开销,但他们应该那么糟糕。我不明白为什么我要+1.1秒。

任何想法?

EDIT

下面是备用的查询。请注意,查询时间不是问题。这是迭代时间。

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

您是如何调整查询的?你刚刚使用了“限制”吗?您应该使用'explain()'功能来更好地了解这两个查询计划,并且可以将其添加到您的问题中。 – 2012-03-13 19:36:22

+0

我在编辑中显示了调整后的查询。虽然查询的执行时间不是问题,但我该如何使用C#中的解释? – IamIC 2012-03-13 19:39:42

+0

而不是使用C#驱动程序进行解释,请使用shell或更好的GUI,比如MongoVUE,这非常棒。你确定它不是查询时间的问题吗?你怎么确定? MongoDB不会一次返回所有结果,它会返回一个游标,它会一次一个记录地从数据库中读取数据,就像应用程序要求的那样(即在迭代过程中) – 2012-03-13 19:42:42

回答

1

的MongoDB不立即返回所有的结果,(在你的迭代IE)返回游标这一次读取关闭数据库中的一个记录数据,您的应用程序需要它这可能是为什么速度较慢。

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

3

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

不确定为什么遍历文档需要比简单计数长得多的时间。其中一个原因可能是服务器只能使用索引来计算计数,但是如果实际遍历文档,服务器必须从磁盘读取每个文档(如果尚未将其分页到内存中)。

这不可能是C#驱动程序反序列化代码中的瓶颈,因为这非常快。

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

+0

我运行了相同的测试,但数据库大小为10%,结果快了30倍,这确认了MDB必须去磁盘 – IamIC 2012-03-14 06:26:12

+0

感谢@罗伯特最后,我已经总结了你在这里说的同样的东西虽然Mongo知道有700多条记录因为索引,因此可以给我答案,它还没有经过它们,它们是分散的,然而,500,000实际上是每一秒的记录,这意味着它有50%的有效顺序读取。 – IamIC 2012-03-14 06:28:23