我有一個場景,我存儲了大量的第三方數據以供業務用戶進行即席分析。大多數針對數據的查詢都會很複雜,使用多個自連接,投影和範圍。DocumentDB PartitionKey和性能
當談到選擇一個PartitionKey
用於天青DocumentDB,我看到有人建議使用邏輯分離,如TenantId,設備ID等
鑑於DocumentDB的並行特性,但是,我很好奇它將如何處理基於某種GUID或大整數的PartitionKey
,以便在大讀取期間,它將被高度並列化。
考慮到這一點,我設計了一個試驗具有兩個集合:
test-col-1
PartitionKey
是TenantId用大致100可能值
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
- Best practices
ConnectionPolicy
ConnectionMode.Direct
,Protocol.Tcp
- 各種
MaxDegreeOfParallelism
值 - 各種
MaxBufferedItemCount
收集具有GUID PartitionKey被查詢與EnableCrossPartitionQuery = true
。我正在使用C#和.NET SDK v1.14.0。
在我使用默認設置初始測試中,我發現,查詢收集與TentantId
作爲PartitionKey是更快,它以平均3,765毫秒相比4,680毫秒的GUID鍵控集合。
當我設置ConnectionPolicy
到Direct
與TCP
,我發現TenantID
集合查詢時間由近1000毫秒減少到平均2865毫秒而GUID集增加了約800毫秒,平均5492毫秒 。
當我開始玩MaxDegreeOfParellelism
和MaxBufferedItemCount
時,事情開始變得有趣。 TentantID
集合查詢時間通常不受影響,因爲查詢不是交叉收集,但是GUID集合顯着加快,達到的值與450 ms(MaxDegreeOfParellelism
= 2000,MaxBufferedItemCount
= 2000)一樣快。
考慮到這些意見,爲什麼你會不想讓PartitionKey
儘可能廣泛的值儘可能?