J'ai un scénario où je stocke de grandes quantités de données tierces pour l'analyse ad-hoc par les utilisateurs professionnels. La plupart des requêtes sur les données seront compliquées, utilisant plusieurs auto-jointures, projections et intervalles.DocumentDB PartitionKey et la performance
Quand il s'agit de choisir un PartitionKey
pour une utilisation dans Azure DocumentDB, je vois des gens qui conseille d'utiliser un séparateur logique tel que TenantID, DeviceId, etc.
Compte tenu de la nature parallèle de DocumentDB, cependant, j'étais curieux comment il traiterait un PartitionKey
basé sur une sorte de GUID ou de grand entier de sorte que, lors de lectures importantes, il serait hautement parellélisé.
Dans cet esprit, je mis au point un test avec deux collections:
test-col-1
PartitionKey
est-TenantID avec environ 100 valeurs possibles
test-col-2
PartitionKey
est une valeur unique attribuée par un tiers qui suit le modèle "AB1234568". Garanti d'être globalement unique par le tiers.
Les deux collections sont mis à 100 000 Ferroviaires.
Dans mon expérience, j'ai chargé les deux collections avec environ 2 000 documents. Chaque document a une taille d'environ 20 Ko et est fortement dénormalisé. Chaque document est un ordre, qui contient plusieurs emplois, qui contiennent chacun des utilisateurs, les prix, etc.
Exemple requête:
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)";
Dans mes tests j'ai ajusté les paramètres suivants:
- Par défaut
ConnectionPolicy
- Best practices
ConnectionPolicy
ConnectionMode.Direct
,Protocol.Tcp
- Divers
MaxDegreeOfParallelism
valeurs - Divers
MaxBufferedItemCount
La collection avec le GUID PartitionKey a été interrogé avec EnableCrossPartitionQuery = true
. J'utilise C# et le .NET SDK v1.14.0.
Dans mes premiers tests avec les paramètres par défaut, je trouve que la collection avec interroge TentantId
comme PartitionKey était plus rapide, avec elle en prenant en moyenne 3765 ms par rapport à 4680 ms sur la collecte GUID-clé.
Quand je mets le ConnectionPolicy
-Direct
avec TCP
, j'ai découvert TenantID
fois la requête de collecte a diminué de près de 1000 ms à une moyenne de 2865 ms tandis que la collecte GUID a augmenté d'environ 800 ms à une moyenne de 5492 ms .
Les choses ont commencé à devenir intéressantes quand j'ai commencé à jouer avec MaxDegreeOfParellelism
et MaxBufferedItemCount
. Les temps de requête de collecte TentantID
n'étaient généralement pas affectés car la requête n'était pas croisée, mais la collecte de GUID accélérait considérablement, atteignant des valeurs aussi rapides que 450 ms (MaxDegreeOfParellelism
= 2000, MaxBufferedItemCount
= 2000).
Compte tenu de ces observations, pourquoi voudriez-vous pas faire la PartitionKey
aussi large que possible une valeur?