【问题标题】:Couchdb super slow view, 100% cpu usageCouchdb 超慢视图,100% cpu 使用率
【发布时间】:2017-02-23 05:25:10
【问题描述】:

有一个帐户文档。该文档有约 1k 个席位。对于每个座位,我们发出一个文档。自然,您会认为这会很慢。 map 函数运行如下:

function(doc) {
    if (doc.type == 'account') {
        doc.seats.map(function(seat) {
            emit(seat.userID, doc))
        } 
    }
}

但是,删除 doc.seats,然后发出更小的文档似乎没有帮助。

function(doc) {
    if (doc.type == 'account') {
        doc.seats.map(function(seat) {
            delete doc.seats
            emit(seat.userID, doc))
        } 
    }
}

有人明白为什么删除席位不会加快速度吗?我们可以加快速度的唯一方法是不发出 doc 对象,而只发出一个 id。

function(doc) {
    if (doc.type == 'account') {
        doc.seats.map(function(seat) {
            emit(seat.userID, doc.id))
        } 
    }
}

这是在沙发视图地图中循环遍历文档数组的问题吗?

【问题讨论】:

    标签: couchdb


    【解决方案1】:

    tldr;

    1. 如果您关心性能,请使用永久视图
    2. doc 在视图中是不可变的。您甚至无法在不复制的情况下添加内容。
    3. 发出 _id 并使用 include_docs 几乎总是比发出整个 doc 作为您的值要好。

    解释

    这里是您的问题的几点,使用您的示例文档,其中包含一个名为席位的数组,包含 1K 个条目。

    在这里发布整个文档是个坏主意。如果这是一个永久视图(如果性能存在问题,您应该始终使用该视图),您已经获取了一份 doc,然后制作了 1000 个副本并通过 seat.userID 对其进行索引。这效率不高。作为临时视图更糟糕,因为它是在每次调用视图时动态生成的,在内存中。

    AFAIK 该文档在通过视图访问时是完全不可变的,因此您尝试删除席位字段的方式不起作用。因此,删除 doc.seats 不应该提供任何性能提升,因为您仍将完成循环并创建原始文档的 1000 个副本。但是,您可以制作不包含席位的 doc 的深层副本,然后通过 emit 传递。

    例如:

    function(doc) {
      var doc_without_seats = JSON.parse(JSON.stringify(doc))
      doc_without_seats['seats'] = null;
      doc.seats.map( function (seat){
        emit(seat.userID, doc_without_seats);
      });
    }
    

    您肯定是在正确的轨道上发出 doc._id 而不是 doc。在这种情况下,您正在构建的索引最大为大小的 1/ 1000。如果仍然需要访问整个文档,可以在查询时将选项 include_docs=true 传递给视图。这样可以防止整个文档被复制到索引中。

    另一个潜在的优化是在通过 seat.userID 查找内容时只发出您想要引用的内容。如果它仍然很大且难以处理,请使用 include_docs 方法。

    【讨论】:

    • 就数据而言,原始文档是席位数组的 99%。因此,如果我发出 doc 减去该数组,那不应该提高吗? -- 实际上,回顾我的代码,删除可能没有像我预期的那样工作,因为我在 .map() 方法中运行它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多