【问题标题】:Azure DocumentDB Query by Id is very slowAzure DocumentDB Query by Id 非常慢
【发布时间】:2018-04-06 03:35:06
【问题描述】:

我有 2 个分区的 16GB 集合。当我通过 ID 查询文档时,速度非常慢。但是通过索引字段查询很快。两者都是跨分区查询,如果我通过查询传递分区键,它会很快,但分区键并不总是可用于我的查询。在 Azure 门户中使用 .NET SDK 和 Document Explorer Query 得到了类似的结果。

该集合具有自定义索引策略,但据我所知,您不需要索引 Id,或者甚至不可能。

这是我的查询及其相应的请求费用。

SELECT * FROM c where c.id = 'unique-id-123'
-- Request Charge: 344940.79 RUs, Document Count: 1

SELECT * FROM c WHERE c.otherId = 'NOT-so-uniqueId-123'
-- Request Charge: 5.08 RUs, Document Count: 3

如您所知,Id 是唯一的,因此查询返回 1 个文档,而第二个查询由 otherId 过滤,它不是那么唯一并返回 3 个文档。还要注意第一个查询的 RU 消耗非常高。

那么为什么第二个查询比 Id 快?


更新:
以下是为上述查询收集的指标。

按 ID 查询:

Read 1 records in 1497 ms, 339173.109 RU, Size: 6873022 KB
QueryPreparationTime(ms): CompileTime = 2, LogicalBuildTime = 0,
     PhysicalPlanBuildTime = 0, OptimizationTime = 0
QueryEngineTime(ms): DocumentLoadTime = 1126, IndexLookupTime = 0,
     RuntimeExecutionTimes = 356, WriteOutputTime = 0

按索引字段查询:

Read 4 records in 2 ms, 7.56 RU, Size: 9 KB
QueryPreparationTime(ms): CompileTime = 0, LogicalBuildTime = 0, 
     PhysicalPlanBuildTime = 0, OptimizationTime = 0
QueryEngineTime(ms): DocumentLoadTime = 0, IndexLookupTime = 1, 
     RuntimeExecutionTimes = 0, WriteOutputTime = 0

这些证明 Id 查询正在进行表扫描,因为大部分时间都来自DocumentLoadTime,而IndexLookupTime 没有任何价值。
但我认为 Id 应该是主键,并且默认情况下按照 @andrew-liu 的 answer 进行索引。

【问题讨论】:

  • 在分区集合中,只有在提供了 id AND 分区键的情况下才能执行主键查找(快速)。如果提供的 id 没有分区键,则查询将恢复为全扫描,因此它速度慢且成本更高。你能提供一组潜在的分区键来搜索吗?例如。 "SELECT * FROM c where c.id = 'id' AND c.pk IN ('pk1', 'pk2', ...)"
  • 感谢@OliverTowers 的回复。不幸的是,很难预测分区键。该查询适用于按 ID 搜索的 API。我添加了用于提供分区键的可选参数,但并非所有预期的客户端都能够提供。感觉真的很奇怪,因为即使使用跨分区搜索,按索引字段(而不是 Id)搜索也很快。

标签: azure azure-cosmosdb


【解决方案1】:

Microsoft 支持人员已作出回应,他们已解决该问题。他们为收藏添加了IndexVersion2。不幸的是,它还不能从门户获得,并且新创建的帐户/收藏仍然没有使用新版本。您必须联系 Microsoft 支持来更改您的帐户。

这是索引版本 2 的集合的新结果,并且有很大的改进。

SELECT * FROM c where c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 344,940.79 RUs
-- Index Version 2: Request Charge: 3.31 RUs

SELECT * FROM c WHERE c.indexedField = 'value' AND c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 150,666.22 RUs 
-- Index Version 2: Request Charge: 5.65 RUs

【讨论】:

  • 谢谢!能否分享一下微软支持的详细回复?他们有没有提到官方修复的发布日期?
【解决方案2】:

“Id”字段仅在分区键中是唯一的。如果您手动配置了索引,这可能就是您的查询成本如此之高的原因。

很遗憾,无法控制“id”字段的索引。如果您索引所有内容,您可以尝试检查查询性能是否有所提高。如果它对您的数据有任何改变,那将会很有趣,尽管它对我的小样本集没有任何改变。

The specified path '/id/?' could not be accepted because it overrides system property 'id'.

根据我的经验,如果每个分区中有几个结果,DocumentDB 查询实际上会变得更便宜。如果分区内没有结果,它们的成本可能会非常高。尝试将具有相同 id 的第二个文档放在不同的分区中,看看性能如何变化。如果没有跨分区查询,则在使用索引字段进行查询时,无论结果计数如何,响应总是非常快。

我从来没有进行过更多调查,因为它从来没有让我对实际用例感到困扰。也可能是每个分区的项目数量没有实际影响,我的数据本身负责。

【讨论】:

  • 感谢您的回答。我尝试在不同的分区键中添加具有相同 ID 的新文档,但它仍然很慢。它甚至将 RU 消耗翻了一番,达到690955.94 RUs。我将尝试使用默认索引策略。
猜你喜欢
  • 2013-07-31
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2012-02-08
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多