从CouchDB中检索许多行性能

时间:2011-09-08 06:12:20

标签: nosql couchdb

我有一个CouchDB数据库,其中包含代表100,000个事件的文档。除其他事项外,每个事件都有一个发生的时间(存储为[年,月,日,小时,分钟,秒]的数组)和分数。我想制作一个平均分数随时间变化的图表。为了做到这一点,我创建了一个带有地图的视图,该地图发出了按间隔排列的密钥,以及用于平均存储桶中密钥的reduce函数。

这很有效。查询总平均值时,CouchDB几乎立即返回结果。当我白天使用并获得大约一百个结果时,我的CouchDB数据库需要几百毫秒来产生结果。使用1000多个桶,查询需要几秒钟才能返回。当这个查询运行时,我的CPU跳转到100%,我的磁盘相当安静。

我对这种放缓感到有些困惑。由于减少一切似乎是即时的,我得出结论,开销可能是生成一个包含1000多个条目的JSON文档。 CouchDB不能以快速的方式返回1000个结果行吗?

我有点像CouchDB新手,所以我的map或reduce功能完全可能很糟糕,或者配置中的某个地方可能有一个标志,允许CouchDB使用更多内存。或者可能是CouchDB仅针对返回许多结果的聚合查询进行了强有力的优化。

么?

1 个答案:

答案 0 :(得分:2)

如果你说'平均'意味着'平均',那么就没有办法直接使用map / reduce对,因为它是递归的(每个递归级别都会引入舍入错误)。

更好的解决方案是收集项目的总和和数量,然后您可以在客户端上平均得出平均值。

听起来你的减速功能是减速的原因,但是在你展示之前我无法分辨。

假设你的地图功能是这个;

function(doc) {
  emit([doc.year, doc.month, doc.day, doc.hour, doc.minute, doc.second], doc.score);
}

你的reduce函数是;

_stats

那么你的结果应该非常快(并且可扩展)。内置的_stats函数将返回这样的结果;

{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}

因此,对于您对视图的任何调用,您都可以得到分数和分数的总和,很容易得出平均值。