【发布时间】: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