使用计数预分配记录
pre-allocation of records using count
我读到记录的预分配可以提高性能,这应该是有益的,尤其是在处理时间序列数据集的许多记录时。
updateRefLog = function(_ref,year,month,day){
var id = _ref,"|"+year+"|"+month;
db.collection('ref_history').count({"_id":id},function(err,count){
// pre-allocate if needed
if(count < 1){
db.collection('ref_history').insert({
"_id":id
,"dates":[{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0},{"count":0}]
});
}
// update
var update={"$inc":inc['dates.'+day+'.count'] = 1;};
db.collection('ref_history').update({"_id":id},update,{upsert: true},
function(err, res){
if(err !== null){
//handle error
}
}
);
});
};
我有点担心必须通过承诺可能会减慢速度,并且可能每次都检查计数会抵消预先分配记录的性能优势。
有没有更高性能的方法来处理这个问题?
"预分配"的一般陈述是关于导致文档"增长"的"更新"操作的潜在成本。如果这导致文档大小大于当前分配的空间,则文档将被"移动"到磁盘上的另一个位置以容纳新空间。这可能很昂贵,因此一般建议编写适合其最终"大小"的文档。
老实说,处理此类操作的最佳方法是首先在分配所有数组元素的情况下执行"upsert",然后仅更新所需的元素。这会减少到"两个"潜在的写入,并且您可以使用批量 API 方法进一步减少到单个"通过网络"操作:
var id = _ref,"|"+year+"|"+month;
var bulk = db.collection('ref_history').initializeOrderedBulkOp();
bulk.find({ "_id": id }).upsert().updateOne({
"$setOnInsert": {
"dates": Array.apply(null,Array(32)).map(function(el) { return { "count": 0 }})
}
});
var update={"$inc":inc['dates.'+day+'.count'] = 1;};
bulk.find({ "_id": id }).updateOne(update);
bulk.execute(function(err,results) {
// results would show what was modified or not
});
或者由于较新的驱动程序倾向于彼此的一致性,因此"批量"部分已降级为常规的WriteOperations
数组:
var update={"$inc":inc['dates.'+day+'.count'] = 1;};
db.collection('ref_history').bulkWrite([
{ "updateOne": {
"filter": { "_id": id },
"update": {
"$setOnInsert": {
"dates": Array.apply(null,Array(32)).map(function(el) {
return { "count": 0 }
})
}
},
"upsert": true
}},
{ "updateOne": {
"filter": { "_id": id },
"update": update
}}
],function(err,result) {
// same thing as above really
});
在任何一种情况下,作为唯一块的$setOnInsert
只会在实际发生"更新插入"时执行任何操作。主要情况是与服务器的唯一联系将是单个请求和响应,而不是等待网络通信的"来回"操作。
这通常是"批量"操作的用途。当您还可以向服务器发送一批请求时,它们会减少网络开销。结果显着加快了速度,除了"有序"除外,这两个操作都不是真正依赖于另一个,这是后一种情况下的默认值,并由遗留.initializeOrderedBulkOp()
明确设置。
是的,"upsert"中有"一点"开销,但与使用 .count()
进行测试并首先等待该结果相比,开销"更少"。
注意:不确定列表中有 32 个数组条目。你可能的意思是 24,但复制/粘贴让你变得更好。无论如何,正如所证明的那样,有比硬编码更好的方法来做到这一点。
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 在循环中分配json值时,值被覆盖
- 动态分配GA增强型电子商务跟踪器
- 将jsp文件下拉列表中的选定项分配给一个java变量(比如String selection)
- 使用Dnamics CRM 2011中的JavaScript读取子网格的所有记录,而不考虑活动页面
- 如何创建带有插槽的vue js组件预加载程序
- 如何在jQuery中将函数的输出分配给变量
- 为集合分配大量的模型弹药
- onclick函数需要双击,因为类分配延迟
- AngularJs对所有页面中的所有记录进行排序
- 在javascript函数中记录输出或分配的变量
- JS循环图像文件夹,预加载它们并分配给数组
- 使用计数预分配记录
- 基于表单输入值,如何 2 生成选择 4 下拉菜单 w 数据库中的行/记录数据,该数据库将在选择时预填充表单
- 如何为下拉菜单生成选择,其中包含数据库中的行/记录数据,该数据库将在选择时预填充表单
- 为什么控制台.log在分配值之前记录值
- 如何通过分配window.location在历史记录中留下链接
- 如何在ExtJS存储中获取记录的预排序索引
- 我正在访问日期的记录:如何分配一个值时,一个特定的日期不存在
- 致命错误:CALL_AND_RETRY_2分配失败-进程在预处理我的js字段时内存不足