Couchdb超慢视图,100%cpu使用率

Couchdb超慢视图,100%cpu使用率,couchdb,Couchdb,有一个账户单据。这个医生有大约1k个座位。对于每个座位,我们发出一个doc。当然,你会认为这是缓慢的。map函数的运行方式如下: function(doc) { if (doc.type == 'account') { doc.seats.map(function(seat) { emit(seat.userID, doc)) } } } 然而,删除doc.seats,然后发出更小的doc似乎没有帮助 function(

有一个账户单据。这个医生有大约1k个座位。对于每个座位,我们发出一个doc。当然,你会认为这是缓慢的。map函数的运行方式如下:

function(doc) {
    if (doc.type == 'account') {
        doc.seats.map(function(seat) {
            emit(seat.userID, doc))
        } 
    }
}
然而,删除doc.seats,然后发出更小的doc似乎没有帮助

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))
        } 
    }
}
这是在沙发视图地图中循环文档数组的问题吗?

tldr

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

  • 解释

    下面是您的问题的两点,使用您的示例文档,该文档包含一个名为seats的数组,其中包含1K个条目

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

    AFAIK文档在通过视图访问时是完全不可变的,因此您试图删除seats字段的方式不起作用。因此,删除doc.seats不会带来任何性能提升,因为您仍将完成循环并创建1000份原始文档的副本。但是,您可以制作一份不包含座位的文档的深度副本,并将其传递给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.\u id而不是doc肯定是正确的。在本例中,您正在构建的索引最大,是大小的1/1000。如果仍然需要访问整个文档,则可以在查询视图时将include\u docs=true选项传递给视图。这样可以防止在索引中复制整个文档


    另一个可能的优化是,在通过seat.userID查找某些内容时,只发出您想要引用的内容。如果这仍然很大且不方便,请使用include_docs方法。

    原始文档在数据方面是seats数组的99%。所以,如果我发射doc减去那个数组,这不应该提高吗?--事实上,回顾我的代码,delete可能没有像我预期的那样工作,因为我在.map()方法中运行它