Firestore过期无用文档应删除还是保留 对查询性能有何影响?
Firestore过期订单文档处理方案解答
先给你说Firestore最核心的性能常识,别被网上一些过时说法误导:Firestore的查询速度只和你本次查询实际拉回来的文档数量挂钩,和集合里总共存了多少条文档没有直接关联。它底层是自动做分布式分片的,只要你的查询带了能命中索引的过滤条件,哪怕你订单集合里攒了几百万条历史数据,精准查某家店、某个用户的有效订单,速度和集合里只有几百条订单的时候完全一致,不会因为总文档量变多就变慢。
你提到的餐饮订单场景的现有文档结构如下:
userID: "UOMXO1C17m3df2WO58Jf" orderTime: July 13, 2022 at 11:22:21 PM UTC+3 restaurantId: "7m3df2WO58Jjkadfladd"
你提到的两个方案都有明显硬伤,没有绝对的“更优”
方案1:直接保留所有过期文档
这个做法不会直接拖慢正常查询的性能,但长期跑下来有三个绕不开的问题:
- 产生不必要的成本:Firestore存储虽然单价不高,但每天几千条、一年就是上百万条,存个三五年光存这些没用的数据也是一笔不小的开销,后续做数据备份、全量导出的时候还要为这些无效数据额外付流量和计算费
- 容易埋下业务隐患:后续版本迭代的时候,万一哪个开发写查询漏加了过滤历史订单的条件,直接把过期订单拉到前端展示、算进当日营收统计里,平白多耗读配额不说,还会出很影响用户体验的线上bug
- 增加运维复杂度:后续要是给集合加新索引、做数据迁移,这些无效文档会把整个操作的时间拉得很长,平白增加运维工作量
方案2:业务走完就由客户端删文档
这个方案比留着文档还不靠谱,完全不建议当主要的清理手段:
- 清理覆盖率没有保障:用户付完钱、看完订单状态直接杀APP、断网、切后台的情况太常见了,删除请求根本发不出去,跑几个月下来照样堆一堆漏删的过期文档,和不删的区别只是堆得慢一点
- 安全风险极高:要让客户端能删订单,你就得在Firestore安全规则里给客户端开对应文档的删除权限,万一规则写得有疏漏,恶意用户抓个包就能把别人的订单全删了,数据很难找回
- 影响端侧体验:删文档要占用户的上行带宽,弱网下还可能挤占正常业务请求的带宽,纯纯给用户添堵
实际落地推荐的做法
别在你说的两个方案里二选一,用服务端定时清理的方案成本最低、可靠性最高:
- 先给你的订单文档加个
expireAt时间戳字段,标记这个订单什么时候算“过期、无业务使用需求” - 配个每天跑一次的定时任务(用Firebase云函数或者你自己的服务端写定时脚本都行),在业务低峰期批量查
expireAt早于当前时间的文档,分批删除,单次删个两三百条就行,不会触发Firestore的写入限流 - 所有查有效订单的业务逻辑,默认都带上
expireAt > 当前服务器时间的过滤条件,配好对应的复合索引,就算偶尔有漏删的文档,也不会被正常请求查到
如果你们有合规要求、需要留存历史订单对账,删之前先把过期文档批量导出到低成本的对象存储里存着就行,成本比存在Firestore里低90%以上,要查历史数据的时候再导回来或者直接读冷存储即可。
内容的提问来源于stack exchange,提问作者Sipan Hazim
相关产品推荐
相关产品推荐

