21-03-2014, 03:41 PM
Salut à tous
Suite à quelques essais sur une BDD MySQL (MyISAM) contenant des champs de type "BIT(1)", je me suis aperçu que l'ajout d'un index peut ralentir une requête SELECT.
En cherchant, l'explication se trouve dans cet article sur la cardinalité des index (en).
Schématiquement, j'en ai compris qu'un index accélère une requête de sélection si la cardinalité de cet index est élevée. La cardinalité représente le nombre de valeurs différentes pour cet index. Ainsi, une clef primaire (index unique) a une cardinalité égale au nombre de lignes de la table, alors qu'un index sur un champ BIT(1) aura une cardinalité de 2 (car seules les valeurs 0 et 1 sont présentent dans ce champs).
Or, plus la cardinalité est élevée, plus le SGDB fait des "élagages" précis et rapides. Quand la cardinalité est faible (2 par exemple), le temps de charger l'index dépasse le temps que cet index fait gagner, et la requête perd en performances.
Ainsi, une requête SELECT dont la clause WHERE porte sur un champ "BIT(1)" est ralentie si un index est ajouté sur ce champ.
Toutefois, une petite exception pour le cas où plus de 99% des valeurs de ce champ sont "0" et que l'on ne souhaite que les valeurs "1" (ou inversement): l'ajout d'un index peut apporter un léger gain. Mais comme cette considération dépend du contenu du champ, je préfère la prendre avec des pincettes, voire l'ignorer.
En conclusion de l'article, j'en déduis que les index ne doivent être utilisés que sur des champs dont la cardinalité (nombre de valeurs prises par ce(s) champ(s)) est élevée.
Si vous avez d'autres ressources sur la bonne utilisation des index MySQL (essayons de ne pas mélanger avec les SQL, PostGre et Mongo dans le même topic), je vous propose de les rajouter en réponse; idem pour vos possibles remarques
Suite à quelques essais sur une BDD MySQL (MyISAM) contenant des champs de type "BIT(1)", je me suis aperçu que l'ajout d'un index peut ralentir une requête SELECT.
En cherchant, l'explication se trouve dans cet article sur la cardinalité des index (en).
Schématiquement, j'en ai compris qu'un index accélère une requête de sélection si la cardinalité de cet index est élevée. La cardinalité représente le nombre de valeurs différentes pour cet index. Ainsi, une clef primaire (index unique) a une cardinalité égale au nombre de lignes de la table, alors qu'un index sur un champ BIT(1) aura une cardinalité de 2 (car seules les valeurs 0 et 1 sont présentent dans ce champs).
Or, plus la cardinalité est élevée, plus le SGDB fait des "élagages" précis et rapides. Quand la cardinalité est faible (2 par exemple), le temps de charger l'index dépasse le temps que cet index fait gagner, et la requête perd en performances.
Ainsi, une requête SELECT dont la clause WHERE porte sur un champ "BIT(1)" est ralentie si un index est ajouté sur ce champ.
Toutefois, une petite exception pour le cas où plus de 99% des valeurs de ce champ sont "0" et que l'on ne souhaite que les valeurs "1" (ou inversement): l'ajout d'un index peut apporter un léger gain. Mais comme cette considération dépend du contenu du champ, je préfère la prendre avec des pincettes, voire l'ignorer.
En conclusion de l'article, j'en déduis que les index ne doivent être utilisés que sur des champs dont la cardinalité (nombre de valeurs prises par ce(s) champ(s)) est élevée.
Si vous avez d'autres ressources sur la bonne utilisation des index MySQL (essayons de ne pas mélanger avec les SQL, PostGre et Mongo dans le même topic), je vous propose de les rajouter en réponse; idem pour vos possibles remarques