2017-02-22 54 views
2

有一个帐户文档。这个文件有1k个席位。对于每个席位,我们发出一个文档。自然,你会期望这会很慢。地图功能像这样运行:Couchdb超慢视图,100%cpu使用率

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)) 
     } 
    } 
} 

这是一个循环在沙发视图地图上的文档的数组问题?

回答

5

tldr;

  1. ,如果你关心性能
  2. 文档是从视图一成不变使用永久视图。你甚至不能在没有复制的情况下添加它。
  3. 发出_id并使用include_docs几乎总是比发送整个doc作为值更好。

解释

这里有几点你的问题,使用含有所谓的座椅,1K条目的数组的示例文档。

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

AFAIK该文档是完全不可变的,因为通过视图访问,所以您试图删除座位字段的方式不起作用。因此,删除doc.seats不应该提供任何性能增益,因为您仍然要完成循环并创建1000个原始文档副本。但是,您可以制作一份没有席位的文档的深层副本,并将其通过发布。

例如:

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方法。

+0

就数据而言,原始文档是99%的座位数组。所以如果我发出减去该数组的文档,是不是应该给予提振? - 其实,回头看我的代码,删除可能不会像我期望的那样工作,因为我正在运行它。map()方法 – Elliot

+0

啊,我相信doc是不可变的。查看我的更新。 – sarwar