当前位置: 首页 > 知识库问答 >
问题:

Azure Cosmos DB Aggregation and indexes

章承
2023-03-14

我正在尝试使用Cosmos DB,但在集合中进行简单计数时遇到了一些问题。

我的集合模式如下,我在这个集合中有80.000个文档。

{
    "_id" : ObjectId("5aca8ea670ed86102488d39d"),
    "UserID" : "5ac161d742092040783a4ee1",
    "ReferenceID" : 87396,
    "ReferenceDate" : ISODate("2018-04-08T21:50:30.167Z"),
    "ElapsedTime" : 1694,
    "CreatedDate" : ISODate("2018-04-08T21:50:30.168Z")
}

如果我运行以下命令来计算集合中的所有文档,我很快就会得到结果:

db.Tests.count()

但是当我对一个特定的用户运行同样的命令时,我得到一条消息“请求率很大”。

db.Tests.find({UserID:"5ac161d742092040783a4ee1"}).count()

在Cosmos DB文档中,我发现了这个场景,并且建议增加RU。目前我的速度是400 RU/s,当我提高到10.000 RU/s时,我能够在5秒内运行命令而不出错。

我已经尝试创建索引显式,但似乎 Cosmos DB 不使用索引进行计数。

我认为在大约100,000份文件的集合中支付10,000 RU/s的简单计数是不合理的,尽管大约需要5秒钟。

共有2个答案

段干长恨
2023-03-14

我认为它就是行不通。

索引似乎是在选择要计数的文档时使用的,但是计数是通过读取每个文档来完成的,因此实际上消耗了大量的RU。

此查询既便宜又快速:

db.Tests.count({ UserID: { '$eq': '5ac161d742092040783a4ee1' }})

但是这个又慢又贵:

db.Tests.count({ ReferenceID: { '$gt': 10 }})

尽管这个查询很快:

db.Tests.find({ ReferenceID: { '$gt': 10 }}).sort({ ReferenceID: 1 })

我也发现了这一点:https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/36142468-make-count-aware-of-indexes。请注意状态:“我们已开始开发此功能。当它正式发布时,将在此处更新。

说实话,非常令人失望,特别是因为这个限制已经将近2年没有得到解决。注意 - 我不是这方面的专家,我很想被证明是错误的,因为我也需要这个功能。

顺便说一句:我注意到简单的索引似乎是为每个单独的字段自动创建的,因此无需手动创建它们。

宇文智敏
2023-03-14

按筛选器计数查询正在使用索引(如果可用)。

如果在未索引列上尝试按筛选器计数,则查询不会超时,但会失败。试试看。您应该得到如下错误:

{"Errors":["针对从索引中排除的路径使用筛选器指定了无效查询。请考虑在请求中添加允许扫描标头。]}

所以一定要在< code>UserID上添加一个合适的索引。

如果您没有索引覆盖并且没有得到上面的错误,那么您可能已经设置了enableScanInQuery标志。这几乎总是一个坏主意,全扫描将不会缩放。这意味着,随着数据集的增长,它将消耗越来越多的RU。因此,请确保它是关闭的,而不是索引。

如果所选列上有索引,则应运行查询。您可以通过发送 x-ms-documentdb-填充查询标头来验证索引是否实际被使用。这应该返回您与索引查找时间InMs索引利用率Ratio字段的确认。输出示例:

“总执行时间InMs=8.44;查询编译时间InMs=8.01;queryLogicalPlanBuildTimeInMs=0.04;query物理计划生成时间InMs=0.06;query优化时间InMs=0.00;VMExecutionTimeInMs=0.14;indexLookupTimeInMs=0.11;documentLoadTimeInMs=0.00;systemFunctionExecuteTimeInMs=0.00;userFunctionExecuteTimeInMs=0.00;检索文档计数=0;检索文档大小=0;outputDocumentCount=1;outputDocumentSize=0;writeOutputTimeInMs=0.01;indexUtilizationRatio=0.00”

它还为您提供了一些见解,如果您觉得RU费用太大,那么工作量已经发展到哪里。

如果索引查找时间本身太高,请考虑您的索引是否足够有选择性以及索引设置是否合适。查看您的UserId值和分布,并相应地调整索引。

另一个需要考虑的猜测是,检查您使用的API是否会延迟执行<code>find(…)是您真正想要的。不清楚您使用的是哪种API。如果在进行计数之前将所有匹配文档提取到客户端,那么这将解释RU成本异常高的原因,尤其是当涉及大量匹配文档或大型文档时。查看API文档。

我还建议直接在Azure Portal中执行相同的查询,以比较RU成本并验证问题是否与客户端相关。

 类似资料:

相关问答

相关文章

相关阅读