Answers:
TL; DR:在Firestore上执行批量日期创建的最快方法是执行并行的单独写入操作。
向Firestore写入1,000个文档需要:
~105.4s
使用顺序的单个写操作时~ 2.8s
使用(2)批处理写操作时~ 1.5s
使用并行的单个写操作时在Firestore上执行大量写入操作的常见方式有三种。
我们将在下面使用随机文档数据数组依次调查每个数据。
这是最简单的解决方案:
async function testSequentialIndividualWrites(datas) {
while (datas.length) {
await collection.add(datas.shift());
}
}
我们依次编写每个文档,直到编写完每个文档。然后,我们等待每个写操作完成,然后再开始下一个操作。
用这种方法写1,000个文档大约需要105秒,因此吞吐量大约是每秒10个文档写入。
这是最复杂的解决方案。
async function testBatchedWrites(datas) {
let batch = admin.firestore().batch();
let count = 0;
while (datas.length) {
batch.set(collection.doc(Math.random().toString(36).substring(2, 15)), datas.shift());
if (++count >= 500 || !datas.length) {
await batch.commit();
batch = admin.firestore().batch();
count = 0;
}
}
}
您可以看到我们BatchedWrite
通过调用来创建一个对象batch()
,填充该对象直到其最大容量为500个文档,然后将其写入Firestore。我们给每个文档一个生成的名称,该名称相对来说可能是唯一的(对于此测试而言足够好)。
用这种方法写1,000个文档大约需要2.8秒,因此吞吐量大约是每秒357个文档写入。
这比顺序进行单个写入要快得多。实际上:许多开发人员之所以使用这种方法是因为他们认为这是最快的方法,但是上面的结果已经表明这是不正确的。由于批次的大小限制,代码是迄今为止最复杂的代码。
对于批量数据输入,请使用具有并行写操作的服务器客户端库。批处理写入的性能要好于串行写入,但不优于并行写入。
我们可以使用以下代码对此进行测试:
async function testParallelIndividualWrites(datas) {
await Promise.all(datas.map((data) => collection.add(data)));
}
此代码以最快的add
速度启动操作,然后用于Promise.all()
等待操作全部完成。使用这种方法,操作可以并行运行。
使用这种方法写入1,000个文档大约需要1.5秒,因此吞吐量约为每秒667个文档写入。
两者的区别不如前两种方法大,但仍比批量写入快1.8倍以上。
一些注意事项:
add()
只不过是生成唯一的ID(纯粹是客户端),然后进行set()
操作。因此结果应该是相同的。如果那不是您所观察到的,请以最小的情况发布一个新问题,以重现您的尝试。