You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加快Firestore批量提交的速度?

如何加快Firestore批量提交的速度?

我最近在做一个需求:用Firestore的查询监听器把Python worker的结果以JSON字符串形式传回浏览器,结果里包含很多Plotly图表,总数据量大概3MB。为了遵守Firestore的文档大小限制,我把JSON拆成了每个300KB的文档,存在一个按顺序键排序的集合里,方便客户端重组。本来想用Python worker的批量提交来减少客户端更新,但发现批量提交的时间居然差不多是单个文档写入时间的总和——就算按照Firebase团队的建议关掉了这个集合的所有索引,情况还是没改善。现在我已经改用Firebase Storage了,确实更合适,但还是好奇这是不是Firestore的固有局限,有没有优化的空间?

预期的理想效果

我本来以为,一旦Python的Firestore客户端初始化完成,批量提交的时间应该主要由两个因素决定:

  • (批量数据大小 / 网络速度):把数据传到Firestore的时间
  • Firestore的文档写入和跨文档相关操作耗时

按这个逻辑,Heroku(我的线上环境,和本地Jupyter测试的耗时差不多)到Google之间传3.6MB的数据大概只要0.1秒,加上关掉所有索引后,Firestore服务器端的写入操作应该不会花太久,总耗时应该能控制在0.5秒以内。

我已经试过的方案

  • 遵循Firestore的最佳实践,关掉了目标集合的所有索引
  • 参考过Firebase社区的讨论,里面提到预期延迟大概100ms左右

我的实验设置

  • 给test_batch_multi集合设置了单字段索引豁免,也就是对所有字段(*)都关闭索引,通过Firestore CLI导出索引配置后,能看到对应的字段覆盖规则:
    "fieldOverrides": [
        {
          "collectionGroup": "test_batch_multi",
          "fieldPath": "*",
          "ttl": false,
          "indexes": []
        }
      ]
    
  • 先写入一个只包含'abc'的文档,测基准耗时:大概125ms
  • 生成一个约300KB的随机字符串作为测试数据
  • 写入单个包含这个字符串的文档,耗时大概500ms(仅本地测试)
  • 批量写入12个同样的文档,90%的情况耗时约4500ms,剩下10%大概1400ms

测试代码

你需要先配置好Firebase Admin环境才能复现,核心代码如下:

首先初始化Firebase相关对象:

import json
import os
import random
import string
import firebase_admin
from firebase_admin import firestore, credentials

# 从环境变量加载Firebase Admin凭证
fb_admin_dict = json.loads(os.getenv('FIREBASE_ADMIN_CRED'))
fb_app = firebase_admin.initialize_app(credentials.Certificate(fb_admin_dict))
fb_db: firestore.Client = firestore.client(fb_app)

# 生成测试用的大字符串(300KB左右)
# json_chunk = 'abc'  # 用来测基准耗时的小数据
json_chunk = ''.join(random.choices(string.ascii_letters + string.digits, k=300000))

测试单个文档的批量提交(批量中仅包含一个文档):

single_coll = fb_db.collection('test_batch')
batch = fb_db.batch()
batch.set(single_coll.document(), {"chunk_num":1, "json_chunk": json_chunk })

# Jupyter环境用%%time计时,非Notebook可替换为logging或其他计时方式
%%time
batch.commit()

测试12个文档的批量提交:

multi_coll = fb_db.collection('test_batch_multi')
batch = fb_db.batch()
for i in range(12):
    batch.set(multi_coll.document(), {"chunk_num":i, "json_chunk": json_chunk })

# 单独统计提交耗时
%%time
batch.commit()

备注:内容来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:34:50