Cosmos DB主键非主键查询RSU一致问题及分区键索引选型咨询
针对两个问题的具体解答
1. 数据量增长后的RU差异与RU计算逻辑
你现在100条数据下两类查询RU完全一致是正常现象:小数据集场景下,两类查询都只命中1条文档,实际产生的CPU、IO、内存开销都落在Cosmos DB的最小计费档位,所以数值没有区别。
等数据规模上涨后,两类查询的RU消耗一定会出现明显差距:
- 按分区键+
id的点读是Cosmos DB中效率最高的操作,1KB大小的文档点读固定消耗1RU,文档体积变大时RU仅随文档大小线性上涨,和容器总数据量、单分区数据量完全无关——不管容器里存100条还是100TB数据,这个操作都是直接走分区内主键索引做O(1)定位,没有额外扫描开销。 - 走非主键二级索引的单值查询,哪怕字段取值全局唯一,RU消耗会随数据规模上涨缓慢升高:二级索引是按范围结构存储的,查询时需要先遍历二级索引树定位条目,再回表读取完整文档,单分区数据量越大,索引查找的IO路径越长,开销就越高;如果这类查询没有传入分区键值,还会触发全分区扇出扫描,RU会随容器总数据量线性上涨,数据量到TB级后性能衰减会非常明显。
关于RU计算逻辑,不存在“按大规模数据场景取平均值”的规则:每一次请求的RU都是实时按实际消耗的资源计算的——扫了多少索引条目、读了多少字节、占用了多少CPU周期,就对应扣多少RU。小数据量下两类请求的实际开销都低于最小计费阈值,所以数值一致,数据量上涨后真实开销的差异会直接体现出来。
2. 新增唯一值非主键查询的架构选型
首先纠正一个认知偏差:Cosmos DB的单个容器仅支持一个分区键,容器创建后分区键不可修改,也不存在“增设分区键”的操作。结合你还未上线生产、可以灵活调整架构的前提,按业务场景选方案即可:
- 如果按新字段的查询是核心高频请求,调用量和按原
id查询的量级相当:不要用二级索引,优先调整分区策略保证两类查询都能走点读。最通用的方案是采用双写模式:将分区键设为通用的查询键字段,同一份业务数据存储两份副本,一份副本的查询键值填原id,另一份填新字段的值,两份副本的业务字段完全一致,这样两类查询都可以通过传入分区键+唯一值实现O(1)点读,性能最稳、RU成本最低。如果不想做双写,也可以使用分层分区键功能,将原id和新字段按查询优先级设为多层分区键,不过这个方案要求查询时按层级顺序传入键值,灵活度稍差。 - 如果按新字段的查询是低频请求,调用量占比不到总请求的10%:不需要调整现有分区键,直接给该字段配置二级索引即可。因为字段取值唯一,查询命中索引后只会返回单条结果,哪怕单分区达到20GB的上限,这类查询的RU也仅比点读高2~5个单位,成本差异完全可以接受,没必要为低频请求重构整个容器的分区设计。
最后提个测试建议:你现在数据量太小,测试结果不具备生产参考价值,建议灌入模拟数据把单分区填充到10GB以上再跑性能测试,得到的RU数据才接近真实生产表现。
内容的提问来源于stack exchange,提问作者user19011893
相关产品推荐
相关产品推荐

