select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
Comment la requête ci-dessus fonctionnera-t-elle en interne dans cassandra ?
Essentiellement, toutes les données de la partition scopeid=35
et formid=78005
seront renvoyées, puis filtrées par l’index record_link_id
. Il recherchera l’entrée record_link_id
pour 9897
, et tentera de faire correspondre les entrées qui correspondent aux lignes renvoyées où scopeid=35
et formid=78005
. L’intersection des lignes pour les clés de partition et les clés d’index sera renvoyée.
Quel index de colonne de cardinalité élevée (record_link_id) affectera les performances de la requête pour la requête ci-dessus?
Les index à haute cardinalité créent essentiellement une ligne pour (presque) chaque entrée de la table principale. Les performances sont affectées, car Cassandra est conçue pour effectuer des lectures séquentielles pour les résultats des requêtes. Une requête d’index oblige essentiellement Cassandra à effectuer des lectures aléatoires. À mesure que la cardinalité de votre valeur indexée augmente, le temps nécessaire pour trouver la valeur interrogée augmente également.
Cassandra touchera-t-elle tous les nœuds pour la requête ci-dessus ? Pourquoi?
Non. Il ne doit toucher qu’un nœud responsable de la partition scopeid=35
et formid=78005
. Les index sont également stockés localement, ne contiennent que des entrées valides pour le nœud local.
la création d’index sur des colonnes à haute cardinalité sera le modèle de données le plus rapide et le meilleur
Le problème ici est que l’approche ne s’adapte pas et sera lente si update_audit
est un grand ensemble de données. Le MVP Richard Low a un excellent article sur les index secondaires (Le Sweet Spot Pour l’indexation secondaire de Cassandra), et en particulier sur ce point:
Si votre table était significativement plus grande que la mémoire, une requête serait très lente même pour ne renvoyer que quelques milliers de résultats. Renvoyer potentiellement des millions d’utilisateurs serait désastreux même si cela semblerait être une requête efficace.
En pratique, cela signifie que l’indexation est la plus utile pour renvoyer des dizaines, voire des centaines de résultats. Gardez cela à l’esprit lorsque vous envisagez ensuite d’utiliser un index secondaire.
Maintenant, votre approche consistant à restreindre d’abord une partition spécifique vous aidera (car votre partition devrait certainement tenir en mémoire). Mais je pense que le choix le plus performant ici serait de faire de record_link_id
une clé de clustering, au lieu de compter sur un index secondaire.
Edit
Comment avoir un index sur un index de cardinalité faible lorsqu’il y a des millions d’utilisateurs évolue même lorsque nous fournissons la clé primaire
Cela dépendra de la largeur de vos lignes. La chose délicate à propos des index de cardinalité extrêmement bas, c’est que le % de lignes retournées est généralement plus grand. Par exemple, considérons une table users
à ligne large. Vous limitez par la clé de partition dans votre requête, mais il y a toujours 10 000 lignes renvoyées. Si votre index est sur quelque chose comme gender
, votre requête devra filtrer environ la moitié de ces lignes, ce qui ne fonctionnera pas bien.
Les indices secondaires ont tendance à mieux fonctionner sur la cardinalité « milieu de la route » (faute de meilleure description). En utilisant l’exemple ci-dessus d’une table users
à ligne large, un index sur country
ou state
devrait fonctionner beaucoup mieux qu’un index sur gender
(en supposant que la plupart de ces utilisateurs ne vivent pas tous dans le même pays ou état).
Edit 20180913
Pour votre réponse à la 1ère question « Comment la requête ci-dessus fonctionnera-t-elle en interne dans cassandra? », savez-vous quel est le comportement lors d’une requête avec pagination?
Considérons le diagramme suivant, tiré de la documentation du pilote Java (v3.6):
Fondamentalement, la pagination provoquera la rupture de la requête et le retour au cluster pour la prochaine itération des résultats. Il serait moins probable que le délai d’expiration soit expiré, mais les performances seront à la baisse, proportionnelles à la taille de l’ensemble de résultats total et au nombre de nœuds dans le cluster.
TL;DR;Plus les résultats demandés sont répartis sur plus de nœuds, plus cela prendra de temps.