【问题标题】:Retrieving many rows performance from CouchDB从 CouchDB 检索多行性能
【发布时间】:2011-11-12 17:11:50
【问题描述】:

我有一个 CouchDB 数据库,其中包含代表 100,000 个事件的文档。除其他事项外,每个事件都有其发生的时间(存储为 [Year,month,day,hour,minute,second] 的数组)和分数。我想制作一个随时间变化的平均分数图。为了做到这一点,我创建了一个视图,其中包含一个映射,该映射发出按间隔存储的键,以及一个对存储桶中的键进行平均的 reduce 函数。

这很好用。当查询总平均值时,CouchDB 几乎立即返回结果。当我每天存储一百个左右的结果时,我的 CouchDB 数据库需要几百毫秒才能产生结果。使用 1000 多个存储桶,查询需要几秒钟才能返回。在运行此查询时,我的 CPU 会跳到 100%,并且我的磁盘相当安静。

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

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

建议?

【问题讨论】:

    标签: nosql couchdb


    【解决方案1】:

    如果当您说“平均”时,您的意思是“平均平均”,则无法直接使用 map/reduce 对得到它,因为它是递归的(每个级别的递归都会引入舍入误差)。

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

    听起来你的 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}
    

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

    【讨论】:

    • 我改用 _stats 并立即体验到 10 倍的性能提升。出于某种原因,我说服自己 reduce 不可能是我减速的原因,但这是完全错误的。我认为我的逻辑是“我可以完全减少所有行,当然做一千次这样的减少不应该花费更长的时间,必须与 JSON 相关。”叹。谢谢!
    • 减速可能是因为只有 一些 个 reduce 值被缓存但不是全部。假设 CouchDB 批量减少 1,000 行,总共 100 批。每个(任意)批次都被缓存,100 个结果被重新减少并被缓存。查询整个答案很快,因为它被缓存了。但是查询 1,900 行需要 couch 重新减少缓存的 1,000 批加上 900 多行。 (更准确地说,B 树的内部节点存储缓存的归约值。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2011-12-17
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多