Azure DocumentDB按ID查询非常缓慢。

7
我有一个包含2个分区的16GB集合。当我通过ID查询文档时,速度非常慢。但是,如果按照索引字段查询,则速度很快。这两种方式都是跨分区查询,如果我在查询中传递分区键,则速度很快,但是我的查询并不总是有可用的分区键。使用.NET SDK和Azure Portal中的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

正如您所知,标识符是唯一的,因此查询将返回1个文档,而第二个查询被otherId过滤,这不是很唯一,并返回3个文档。同时请注意第一次查询的极高RUs消耗。

那么为什么第二个查询比按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没有值。
但是根据@andrew-liu的答案,我认为Id应该是默认索引的主键。

在分区集合中,只有在提供id和分区键时才能执行主键查找(快速)。如果仅提供id而没有提供分区键,则查询将回归到全扫描,因此速度较慢且更昂贵。您能否提供一组可能的分区键进行搜索?例如:“SELECT * FROM c where c.id = 'id' AND c.pk IN ('pk1', 'pk2', ...)” - Oliver Towers
2
感谢您的回复@OliverTowers。不幸的是,预测分区键将会很困难。该查询是针对通过Id搜索的API。我已添加了可选参数以提供分区键,但并非所有预期的客户端都能够提供该参数。这感觉真的很奇怪,因为即使进行跨分区搜索,按索引字段(而不是Id)进行搜索也很快。 - Mark Trinidad
2个回答

8

微软技术支持已经回复并解决了问题。他们为此收集添加了IndexVersion 2。不幸的是,它还没有在门户中提供,新创建的帐户/收集仍未使用新版本。您需要联系微软支持来更改您的帐户。

以下是具有索引版本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

3
谢谢!你还能分享微软支持团队的详细回复吗?他们提到了正式修复的发布日期吗? - driAn

0

"Id"字段仅在分区键中是唯一的。这可能是您的查询非常昂贵的原因之一,如果您手动配置了索引。

很遗憾,无法控制'id'字段的索引。您可以尝试检查是否将所有内容都进行索引会改善查询性能。对于您的数据而言,如果有什么变化的话,那将会很有趣,尽管对于我的小样本集来说没有任何变化。

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

根据我的经验,如果每个分区中有几个结果,DocumentDB查询实际上可以变得更便宜。如果一个分区中没有结果,它们可能非常昂贵。尝试在不同的分区中放置具有相同ID的第二个文档,并查看性能如何改变。在使用索引字段进行查询时,即使结果计数不同,没有跨分区查询,响应始终非常快。

我从未深入研究过,因为它从未真正困扰过我。也可能是每个分区中的项目数量没有真正影响,而是我的数据本身负责。


谢谢你的回答。我尝试使用不同分区键添加具有相同Id的新文档,但它仍然非常慢。它甚至将RUs消耗量增加了一倍,达到了690955.94 RUs。我会尝试对默认索引策略进行实验。 - Mark Trinidad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接