Une cardinalité plus élevée signifie de meilleures performances de lecture car, par définition, il y a moins d'enregistrements à lire.
Pour traiter une requête comme celle-ci :
SELECT *
FROM mytable
WHERE indexed_col = @myvalue
, le moteur doit suivre les étapes suivantes :
-
Trouver la première entrée satisfaisant la condition.
Cela se fait en traversant le
B-Tree
, à partir de l'entrée racine.À travers les pages, la recherche est effectuée en suivant
B-Tree
liens; au sein d'une page, la recherche est effectuée en utilisant la recherche binaire (sauf si vos clés sont compressées, auquel cas il s'agit d'une recherche linéaire).Cet algorithme a la même efficacité pour les colonnes à cardinalité élevée et à cardinalité faible. Trouver le premier
3
(par opposition à n'importe quel3
) dans ces listes :1 2 3 4 5 6 7 8 9 10 3 3 3 3 3 3 3 3 4 4
nécessite le même
O(log(n))
étapes. -
Parcours de l'index jusqu'à ce que la valeur de la clé change. Ceci, bien sûr, nécessite un temps linéaire :plus vous avez d'enregistrements, plus vous devez parcourir.
Si vous n'avez besoin que du premier enregistrement :
SELECT *
FROM mytable
WHERE indexed_col = @myvalue
LIMIT 1
, la cardinalité des colonnes n'affecte pas les performances de lecture.
Chaque clé d'index a une valeur supplémentaire cachée :un pointeur d'enregistrement. C'est tout l'intérêt d'avoir un index :vous devez savoir vers quel enregistrement il pointe.
Puisqu'un pointeur d'enregistrement, par définition, est unique, chaque clé d'index est également unique. Les entrées d'index partageant la même valeur de clé sont triées par le pointeur d'enregistrement.
Cela permet de rendre l'index maintenable :si vous supprimez un enregistrement avec une valeur d'une colonne indexée partagée par un million d'autres enregistrements, l'enregistrement d'index correspondant doit également être supprimé. Mais le million entier d'enregistrements d'index n'est pas parcouru :à la place, le pointeur d'enregistrement est utilisé comme condition de recherche supplémentaire.
Chaque clé d'index est en fait unique (même si vous ne définissez pas l'index comme unique) et, par conséquent, a la cardinalité maximale possible.
La réponse à vos questions est donc :non, la cardinalité de la colonne n'affecte pas les performances d'écriture de l'index.