web-dev-qa-db-fra.com

Y a-t-il un gain de performances dans l'indexation d'un champ booléen?

Je suis sur le point d'écrire une requête qui inclut un WHERE isok=1. Comme son nom l'indique, isok est un champ booléen (en fait une TINYINT(1) UNSIGNED qui est définie sur 0 ou 1 selon les besoins).

Y a-t-il un gain de performances dans l'indexation de ce champ? Le moteur (InnoDB dans ce cas) fonctionnerait-il mieux ou moins bien dans la recherche de l'indice?

83

Pas vraiment. Vous devriez y penser comme un livre. S'il n'y avait que 3 types de mots dans un livre et que vous les indexiez tous, vous auriez le même nombre de pages d'index que les pages normales.

Il y aurait un gain de performances s'il y a relativement peu d'enregistrements d'une valeur. Par exemple, si vous avez 1 000 enregistrements et 10 d'entre eux sont VRAIS, il serait utile de rechercher avec isok = 1

Comme Michael Durrant l'a mentionné, cela ralentit également les écritures.

EDIT: Duplication possible: Indexation des champs booléens

Ici, il explique que même si vous avez un index, si vous avez trop d'enregistrements, il n'utilise pas l'index de toute façon. MySQL n'utilise pas d'index lors de la vérification = 1, mais l'utilise avec =

60
Michael Koper

Juste pour mettre un point plus fin sur plusieurs autres réponses ici, car d'après mon expérience, ceux qui examinent des questions comme celle-ci sont dans le même bateau que nous, nous avons tous entendu que l'indexation des champs booléens est inutile, et pourtant ...

Nous avons une table avec environ 4 millions de lignes, seulement 1000 environ à la fois auront un commutateur booléen marqué et c'est ce que nous recherchons. L'ajout d'un index sur notre champ booléen a accéléré les requêtes par ordre de grandeur, il est passé d'environ 9+ secondes à une fraction de seconde.

89
oucil

Cela dépend des requêtes réelles et de la sélectivité de la combinaison index/requête.

Cas A: condition WHERE isok = 1 et rien d'autre:

SELECT *
FROM tableX
WHERE isok = 1
  • Si l'index est suffisamment sélectif (disons que vous avez 1 M de lignes et seulement 1 k ont ​​isok = 1), alors le moteur SQL sera probablement tilisez l'index et sera plus rapide que sans lui.

  • Si l'index n'est pas suffisamment sélectif (supposons que vous ayez 1 million de lignes et plus de 100 000 ont isok = 1), alors le moteur SQL va probablement ne pas utiliser l'index et faire un scan de table.

Cas B: condition WHERE isok = 1 et plus encore:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

Ensuite, cela dépend des autres index dont vous disposez. Un index sur another_column serait probablement plus sélectif que l'index sur isok qui n'a que deux valeurs possibles. Un index sur (another_column, isok) ou (isok, another_column) serait encore mieux.

22
ypercubeᵀᴹ

Non, généralement pas.

Vous indexez généralement les champs à rechercher lorsqu'ils présentent une sélectivité/cardinalité élevée. La cardinalité d'un champ booléen est très faible dans la plupart des tableaux. Cela réduirait également la vitesse de vos écritures.

6
Michael Durrant

Oui, un index améliorera les performances, vérifiez la sortie d'EXPLAIN avec et sans l'index.

De la documentation:

Les index sont utilisés pour rechercher rapidement des lignes avec des valeurs de colonne spécifiques. Sans index, MySQL doit commencer par la première ligne, puis parcourir toute la table pour trouver les lignes pertinentes. Plus la table est grande, plus cela coûte. Si la table a un index pour les colonnes en question, MySQL peut rapidement déterminer la position à rechercher au milieu du fichier de données sans avoir à regarder toutes les données.

Je pense qu'il est également prudent de dire qu'un index ne diminuera pas [~ # ~] [~ # ~] les performances dans ce cas, vous n'avez donc qu'à en tirer profit.

4
ilanco

Cela dépend de la distribution des données.

Imaginez que j'avais un livre avec 1000 pages étroitement dactylographiées, et les seuls mots de mon livre étaient "oui" et "non" répétés encore et encore et distribués au hasard. Si on me demandait d'encercler toutes les instances de "oui", un index au dos du livre aiderait-il? Ça dépend.

S'il y avait une répartition aléatoire moitié-moitié des oui et des non, alors rechercher dans l'indice ne serait d'aucune utilité. L'index rendrait le livre beaucoup plus gros, et de toute façon je serais plus rapide juste de commencer par l'avant et de parcourir chaque page en recherchant toutes les instances de "oui" et en les encerclant, plutôt que de rechercher chaque élément dans l'index, puis en prenant la référence de l'entrée d'index à la page à laquelle il se réfère.

Mais s'il n'y avait, disons, que dix exemples de "oui" dans mon livre de mille pages et que tout le reste n'était que des millions de non, alors un index me ferait gagner beaucoup de temps pour trouver ces dix exemples de "oui" et les encercler. .

C'est la même chose dans les bases de données. S'il s'agit d'une distribution 50:50, alors un index ne va pas aider - le moteur de base de données est mieux de simplement parcourir les données du début à la fin (analyse complète de la table), et l'index ne ferait qu'agrandir la base de données, et plus lent à écrire et à mettre à jour. Mais si c'est quelque chose comme une distribution 4000: 1 (selon oucil dans ce fil), alors une recherche d'index peut l'accélérer énormément, si ce sont les éléments 1 sur 4000 que vous recherchez .

4
Jinlye

En fait, cela dépend des requêtes que vous exécutez. Mais, généralement oui, ainsi que l'indexation d'un champ de tout autre type.

3
Maksym Polshcha