Lire tout un million de commandes ?
Une boutique en ligne garde un million de commandes. Une cliente veut voir les siennes. La boutique lit-elle le million pour les trouver ?
Une bonne table DynamoDB ne le fait pas. Une requête va droit aux commandes de la cliente et ne lit rien d’autre. Cette leçon montre pourquoi une requête coûte moins qu’un scan, et comment lire les compteurs que le service renvoie.
À la fin de cette leçon
Remarque
Je peux dire pourquoi une requête coûte moins qu’un scan.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Clé de partition | l’attribut qui décide où un élément est rangé | |
| Clé de tri | l’attribut qui met les éléments dans l’ordre, à l’intérieur d’une clé de partition | |
| Condition de clé | le test qu’une requête fait sur les clés | |
| Requête | une lecture qui va vers une seule clé de partition | query |
| Scan | une lecture qui regarde chaque élément de la table | |
| Filtre | un test appliqué après la lecture des éléments |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Deux clés donnent une adresse à chaque élément
Notre table de commandes a deux attributs clés. La clé de partition est client. Elle décide où le service range un élément, donc toutes les commandes d’un même client sont ensemble.
La clé de tri est numero_commande. Elle met en ordre les commandes d’un client. Ensemble, les deux clés désignent un seul élément. Deux commandes peuvent avoir le même client, mais jamais les deux mêmes clés.
Exemple travaillé : le rangement des commandes
| Clé de partition : client | Clé de tri : numero_commande | Autres attributs |
|---|---|---|
| ana | 1 | thé, payée, total 4 |
| ana | 2 | lait, nouvelle, total 2 |
| ana | 3 | gâteau, payée, total 15 |
| ben | 7 | thé, payée, total 8 |
| cai | 4 | lait, nouvelle, total 6 |
| cai | 9 | thé, payée, total 3 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Requête : un endroit, scan : partout
Une requête nomme la clé de partition. Elle le doit, sinon le service refuse avec une ValidationException et le statut HTTP 400. Le service va droit à ce client et ne lit que ses commandes.
Un scan ne nomme rien. Il lit chaque élément de la table, l’un après l’autre. Les deux réponses portent un Count, le nombre d’éléments renvoyés, et un ScannedCount, le nombre d’éléments regardés.
Essayez : une requête et un scan
commandes = [
{"client": {"S": "ana"}, "numero_commande": {"N": "1"}, "statut": {"S": "payée"}},
{"client": {"S": "ana"}, "numero_commande": {"N": "2"}, "statut": {"S": "nouvelle"}},
{"client": {"S": "ana"}, "numero_commande": {"N": "3"}, "statut": {"S": "payée"}},
{"client": {"S": "ben"}, "numero_commande": {"N": "7"}, "statut": {"S": "payée"}},
{"client": {"S": "cai"}, "numero_commande": {"N": "4"}, "statut": {"S": "nouvelle"}},
{"client": {"S": "cai"}, "numero_commande": {"N": "9"}, "statut": {"S": "payée"}},
]
def faire_scan(elements):
return {"Count": len(elements), "ScannedCount": len(elements)}
def faire_requete(elements, client):
trouves = []
for element in elements:
if element["client"]["S"] == client:
trouves.append(element)
return {"Count": len(trouves), "ScannedCount": len(trouves)}
print("scan :", faire_scan(commandes))
print("requête ana :", faire_requete(commandes, "ana"))
# Remplacez "ana" par "ben". Combien d’éléments la requête regarde-t-elle maintenant ?
Un filtre réduit la réponse, pas le travail
Une condition de clé peut aussi tester la clé de tri. Par exemple, un numero_commande de 2 ou plus. Le service ne lit alors que cette partie de la partition.
Un filtre teste un autre attribut, comme le statut. Il s’applique après la lecture des éléments, donc il change le Count mais pas le ScannedCount.
Exemple : les commandes payées d’ana, dès la 2
| Étape | Éléments restants | Ce qui s’est passé |
|---|---|---|
| La clé de partition est ana | 3 | les commandes 1, 2 et 3 |
| Clé de tri de 2 ou plus | 2 | les commandes 2 et 3, donc ScannedCount vaut 2 |
| Filtre : le statut est payée | 1 | la commande 3 seule, donc Count vaut 1 |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Erreur fréquente
Attention
Beaucoup croient qu’un filtre rend une lecture moins chère. Ce n’est pas vrai. Le service lit les éléments d’abord et en écarte après. Mettez dans la condition de clé tout ce que vous pouvez, et gardez le filtre pour le reste.
Essayez : lire les deux compteurs
reponse = {
"Count": 1,
"ScannedCount": 2,
"Items": [
{"client": {"S": "ana"}, "numero_commande": {"N": "3"}, "statut": {"S": "payée"}},
],
}
ecartes = reponse["ScannedCount"] - reponse["Count"]
print("regardés :", reponse["ScannedCount"])
print("renvoyés :", reponse["Count"])
print("écartés par le filtre :", ecartes)
# Remplacez ScannedCount par 3. Combien d’éléments le filtre a-t-il écartés ?