Firestore非均衡数据集下索引合并性能及相关疑问
Firestore单属性索引合并与复合索引的性能权衡解析
Google Cloud文档中明确了单属性索引合并与复合索引的性能权衡规则:
索引合并的最佳性能场景是索引中的所有潜在匹配项都满足查询过滤条件,此时性能为O(R * I),其中R是结果集大小,I是扫描的索引数量。
最差性能场景是数据库需考虑大量潜在匹配项,但其中仅有少数满足查询过滤条件,此时性能为O(S),其中S是单次索引扫描得到的最小潜在实体集的大小。
最佳性能场景示例
比如执行以下查询:
db.collection('employees').where('department','==','accounting').where('diploma','==','CPA')
假设所有会计部门员工都持有CPA证书,所有从单属性索引中匹配到的潜在实体都满足查询条件。如果结果集有5条数据,性能复杂度为O(5*2)=O(10),属于最优情况。
最差性能场景示例
再看这个查询:
db.collection('athletes').where('country','==','jamaica').where('sport','==','bobsleigh')
牙买加运动员、全球雪橇运动员的数量都不少,但同时满足两个条件的人极少。这里的S指的是两个单属性索引扫描结果中潜在实体数量更小的那个(哪怕这个数值依然很大),此时性能复杂度为O(S),效率极低,这种场景下必须使用复合索引。
存疑场景的性能分析
针对这个查询:
db.collection('novels').where('author','==','stephen king').where('in-print','==',true)
斯蒂芬·金的小说约有65本,而在售书籍总数有数百万本,且他的多数小说都处于在售状态。此时索引合并会基于潜在实体集更小的那个索引(也就是斯蒂芬·金的65本小说)来处理:zigzag算法会先获取这个小数据集,再逐一验证是否满足在售条件,完全不需要遍历数百万本在售书籍。因此性能表现良好,不需要额外创建复合索引。
查询条件顺序对性能的影响
如果调整查询条件的顺序为:
db.collection('novels').where('in-print','==',true).where('author','==','stephen king')
Firestore的查询优化器会自动识别并选择潜在实体集更小的索引作为处理起点,不会去遍历数百万本在售小说。无论你写的条件顺序如何,最终的处理逻辑和性能表现都和原查询一致。
内容的提问来源于stack exchange,提问作者Laurent
相关产品推荐
相关产品推荐

