关于Azure Cosmos DB索引分区归属、非分区键字段索引有效性及查询性能的技术问询
关于Azure Cosmos DB索引分区归属、非分区键字段索引有效性及查询性能的技术问询
嗨,这个问题问到点子上了,刚好是Cosmos DB里分区和索引交互的核心细节,我给你梳理明白:
首先得明确一个关键规则:每个逻辑分区都拥有独立的索引实例,哪怕多个逻辑分区被Cosmos DB调度到同一个物理分区里存储,它们的索引还是完全分开的——物理分区只是底层的资源调度单元,不影响逻辑分区索引的独立性。
回到你的问题:
- 当你把分区键设为
id(相当于每个文档都是一个独立的逻辑分区)时,非分区键的索引不是完全没用,但性能表现会很差。比如你查询name = "John"时,Cosmos DB需要遍历所有逻辑分区的name索引,每个分区做一次索引查找,然后把结果聚合起来。这里的n就是逻辑分区的数量(也就是你的文档总数),哪怕这些逻辑分区都在同一个物理分区里,也得挨个查一遍。 - 你提到的默认索引策略下,
name字段确实会被自动索引,但每个逻辑分区的name索引里只包含该分区内的那一条文档数据——说白了就是每个索引里只有一个条目,查询时还是得把所有这些小索引都扫一遍。
针对你的具体例子:
查询:
SELECT * from c WHERE c.name = "John"
这个查询会用到name字段的索引,但不是一次索引查找就能搞定的:它会触发跨所有逻辑分区的索引扫描,每个逻辑分区单独执行一次索引查找操作,最后合并结果。哪怕所有逻辑分区都在同一个物理分区里,这个过程也不会变成单次索引查找——因为逻辑分区的索引是完全隔离的,物理分区只是把它们放在一起存储而已,索引的独立性还是要保证的。
最后给你个小建议:如果你的业务经常需要单独按name查询,把id作为分区键是非常不划算的,这种查询本质上就是全分区扫描(哪怕是基于索引的)。建议根据你的核心查询模式来选择分区键,比如如果经常按name查询,可以考虑把name作为分区键;如果是id+name的组合查询,那用id做分区键没问题,但单独查name的场景就得接受这种跨分区索引扫描的性能损耗。
备注:内容来源于stack exchange,提问作者Dmitry Klochkov
相关产品推荐
相关产品推荐

