Cosmos DB不同吞吐量下RU消耗异常及检索数据量不符问题咨询
Cosmos DB查询性能异常问题分析
场景描述
在Azure门户的Cosmos DB Data Explorer中测试查询性能时,遇到了可复现但难以理解的行为:
查询语句
SELECT c.displayname FROM c WHERE STARTSWITH(c.displayname,'Large object',true) ORDER BY c.completedtime DESC
集合基础信息
- 单一物理分区,分区键为文档ID
- 包含约30万个对象,总存储大小2GB(含600MB索引)
- 查询匹配1277个大文档(单文档约150KB),但仅投影短属性
displayname
不同吞吐量下的查询表现
- 400 RU/s:总消耗268,860 RUs,耗时约半小时
- 核心统计:检索文档数129073;检索文档大小69GB(异常);输出文档数101;索引命中文档数129073;索引查找时间1689ms;文档加载时间116399ms;查询引擎执行时间479ms;往返次数1
- 2000 RU/s:总消耗5806 RUs,耗时约2秒
- 核心统计:检索文档数2717;检索文档大小1.4GB;输出文档数170;索引命中文档数2717;索引查找时间33ms;文档加载时间2601ms;查询引擎执行时间35ms;往返次数1
问题解答
1. 为何400 RU/s下的RU消耗是2000 RU/s时的近50倍?
这是低吞吐量导致查询限流重试,叠加Cosmos DB RU计算机制的结果:
- Cosmos DB查询分索引筛选、排序、分页返回等阶段。当吞吐量(RU/s)不足以支撑查询的瞬时资源需求时,查询会被限流,但不会直接失败,而是会反复重试读取数据。每一次重试都会额外消耗RU。
- 400 RU/s的吞吐量无法一次性完成索引遍历和文档加载,查询引擎被迫多次重复读取相同的索引条目和文档,累计推高了总RU消耗。而2000 RU/s的吞吐量足够覆盖查询的瞬时资源需求,查询可以一次性完成全流程,没有重试,RU消耗仅为实际所需的量。
- 低吞吐量下查询耗时极长,期间可能因Cosmos DB内部调度导致查询上下文部分重置,进一步增加重复读取次数,加剧RU的额外消耗。
2. 集合总存储仅1.6GB,为何检索文档大小能达到69GB?
这个异常数值是重复读取的累计总和:
- 统计中的“检索文档大小”是查询执行过程中所有读取操作的大小累加值,而非单次读取的大小。当查询被限流重试时,每一次重试都会重新读取部分或全部匹配的文档,多次累加后就会出现远大于集合实际存储的数值。
- 2000 RU/s场景下没有重试,检索大小就是实际需要读取的文档总大小(匹配的1277个文档加上排序预读的部分文档,共约2717个,对应1.4GB)。
内容的提问来源于stack exchange,提问作者Mo B.
相关产品推荐
相关产品推荐

