大量插入pg-promise

我正在使用pg-promise ,我想对多个表进行插入。 我已经看到一些解决scheme,如pg-promise的多行插入,以及如何正确地将多行插入PG和node-postgres? ,我可以使用pgp.helpers.concat来连接多个select。

但现在,我需要在一个表中插入大量的测量数据,超过10,000条logging,并在https://github.com/vitaly-t/pg-promise/wiki/Performance-Boost中说:“有多less条logging你可以像这样连接 – 取决于logging的大小,但是我不会用这种方法超过10,000条logging,所以如果你需要插入更多的logging,你可能想把它们拆分成连续的批处理,然后执行它们逐个。”

我读了所有的文章,但我不知道如何“分割”我的插入批处理,然后逐个执行它们。

谢谢!

UPDATE

最好是阅读以下文章: 数据导入 。


作为pg-promise的作者,我不得不最终为这个问题提供正确的答案,因为之前发表的论文并没有真正做到公正。

为了插入大量/无限数量的logging,您的方法应该基于方法顺序 ,这在任务和事务中是可用的。

var cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tableName'}); // returns a promise with the next array of data objects, // while there is data, or an empty array when no more data left function getData(index) { if (/*still have data for the index*/) { // - resolve with the next array of data } else { // - resolve with an empty array, if no more data left // - reject, if something went wrong } } function source(index) { var t = this; return getData(index) .then(data => { if (data.length) { // while there is still data, insert the next bunch: var insert = pgp.helpers.insert(data, cs); return t.none(insert); } // returning nothing/undefined ends the sequence }); } db.tx(t => t.sequence(source)) .then(data => { // success }) .catch(error => { // error }); 

从性能angular度和负载调节两方面来看,这是将大量行插入数据库的最佳方法。

您所要做的就是根据您的应用程序的逻辑来实现您的函数getData ,即基于序列index的大数据来自何处,一次返回大约1,000 – 10,000个对象,具体取决于大小对象和数据可用性。

另请参阅一些API示例:

  • spex – >序列
  • 链接和分离sorting
  • stream媒体和分页

相关的问题: 节点postgres与大量的查询 。


在需要获取所有插入logging的生成ID的情况下,您可以按如下方式更改两行:

 // return t.none(insert); return t.map(insert + 'RETURNING id', [], a => +a.id); 

 // db.tx(t => t.sequence(source)) db.tx(t => t.sequence(source, {track: true})) 

只是要小心,因为在内存中保留太多的loggingID可能会造成过载。

我认为这种天真的做法是可行的。

尝试将您的数据分成多个10,000条或更less的logging。 我会尝试使用这个post的解决scheme分裂数组。

然后,多行插入每个具有pg-promise的数组,并在事务中逐个执行它们。

编辑:感谢@ vitaly-t美妙的图书馆和改善我的答案

另外不要忘记在事务中包装你的查询,否则会耗尽连接。

要做到这一点,请使用pg-promise的批处理函数asynchronousparsing所有查询:

 // split your array here to get splittedData int i = 0 var cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tmp'}) // values = [..,[{col_a: 'a1', col_b: 'b1'}, {col_a: 'a2', col_b: 'b2'}]] let queries = [] for (var i = 0; i < splittedData.length; i++) { var query = pgp.helpers.insert(splittedData[i], cs) queries.push(query) } db.tx(function () { this.batch(queries) }) .then(function (data) { // all record inserted successfully ! } .catch(function (error) { // error; });