我有一个场景,其中存储了大量第三方数据,以供业务用户进行临时分析。使用多个自联接,投影和范围,对数据的大多数查询将很复杂。
在选择要在Azure DocumentDB中使用的PartitionKey
时,我看到有人建议使用逻辑分隔符,例如TenantId,DeviceId等。
但是,考虑到DocumentDB的并行性质,我很好奇它如何处理基于某种GUID或大整数的PartitionKey
,以便在大读取期间将其高度并行化。
考虑到这一点,我设计了一个包含两个集合的测试:
test-col-1
PartitionKey
是带有大约100个可能值的TenantId test-col-2
PartitionKey
是第三方遵循模式“AB1234568”分配的唯一值。由第三方保证在全局范围内是唯一的。 两个集合都设置为100,000 RU。
在我的实验中,我为这两个馆藏加载了大约2,000个文档。每个文档的大小约为20 KB,并且高度非规范化。每个文档都是一个订单,其中包含多个作业,每个作业都包含用户,价格等。
查询示例:
SELECT
orders.Attributes.OrderNumber,
orders.Attributes.OpenedStamp,
jobs.SubOrderNumber,
jobs.LaborTotal.Amount As LaborTotal,
jobs.LaborActualHours As LaborHours,
jobs.PartsTotal.Amount As PartsTotal,
jobs.JobNumber,
jobs.Tech.Number As TechNumber,
orders.Attributes.OrderPerson.Number As OrderPersonNumber,
jobs.Status
FROM orders
JOIN jobs IN orders.Attributes.Jobs
JOIN tech IN jobs.Techs
WHERE orders.TenantId = @TentantId
AND orders.Attributes.Type = 1
AND orders.Attributes.Status IN (4, 5)";
在测试中,我调整了以下设置:
ConnectionPolicy
ConnectionPolicy
ConnectionMode.Direct
,Protocol.Tcp
MaxDegreeOfParallelism
值MaxBufferedItemCount
使用
EnableCrossPartitionQuery = true
查询具有GUID PartitionKey的集合。我正在使用C#和.NET SDK v1.14.0。在具有默认设置的初始测试中,我发现以
TentantId
作为PartitionKey来查询集合的速度更快,与GUID键的集合上的 4,680 ms 相比,平均花费 3,765 ms 当我将
ConnectionPolicy
设置为Direct
和TCP
时,我发现TenantID
集合的查询时间减少了将近1000毫秒,平均为 2,865毫秒,而GUID集合的查询时间增加了约800毫秒,平均为 5,492毫秒。当我开始使用
MaxDegreeOfParellelism
和MaxBufferedItemCount
时,事情开始变得有趣起来。 TentantID
收集查询时间通常不会受到影响,因为查询不是交叉收集,但是GUID收集大大加快了速度,达到 450毫秒的速度(MaxDegreeOfParellelism
= 2000,MaxBufferedItemCount
= 2000)。鉴于这些观察,为什么不希望将
PartitionKey
的值设置为尽可能宽泛的? 最佳答案
MaxDegreeOfParallelism可以设置ParallelOptions实例启用的最大并发任务数。如我所知,这是客户端并行处理,这将花费您在站点上拥有的CPU/内存资源。
对于写操作,我们可以跨分区键扩展,以使用您已预配的整个键。对于读取操作,我们需要最小化跨分区查找以降低延迟。
另外,如本正式文件所述:
有关更多详细信息,您可以引用How to partition and scale in Azure Cosmos DB和有关Azure DocumentDB Elastic Scale - Partitioning的本第9 channel 教程。
关于azure - DocumentDB PartitionKey和性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44128354/