Les index dans MySQL sont une bête très complexe. Nous avons couvert les index MySQL dans le passé, mais nous ne les avons jamais approfondis - nous le ferons dans cette série d'articles de blog. Ce billet de blog devrait servir de guide très général sur les index tandis que les autres parties de ces séries plongeront un peu plus profondément dans ces sujets.
Que sont les index ?
En général, comme déjà noté dans un article de blog précédent sur les index, un index est une liste alphabétique d'enregistrements avec des références aux pages sur lesquelles ils sont mentionnés. Dans MySQL, un index est une structure de données qui est le plus souvent utilisée pour trouver rapidement des lignes. Vous pouvez également entendre le terme "clés" - il fait également référence aux index.
Que font les index ?
Dans MySQL, les index sont utilisés pour trouver rapidement des lignes avec des valeurs de colonne spécifiques et pour empêcher la lecture de toute la table pour trouver des lignes pertinentes pour la requête. Les index sont principalement utilisés lorsque les données stockées dans un système de base de données (par exemple, MySQL) deviennent plus volumineuses, car plus la table est grande, plus la probabilité que vous puissiez bénéficier des index est grande.
Types d'index MySQL
En ce qui concerne MySQL, vous avez peut-être entendu parler de plusieurs types d'index :
-
Un B-Tree INDEX - un tel index est fréquemment utilisé pour accélérer les requêtes SELECT correspondant à une clause WHERE. Un tel index peut être utilisé sur des champs où les valeurs n'ont pas besoin d'être uniques, il accepte également les valeurs NULL.
-
UN INDEX FULLTEXT - un tel index est utilisé pour utiliser les capacités de recherche en texte intégral. Ce type d'index trouve des mots-clés dans le texte au lieu de comparer directement les valeurs aux valeurs de l'index.
-
UN INDEX UNIQUE est fréquemment utilisé pour supprimer les valeurs en double d'une table. Applique l'unicité des valeurs de ligne.
-
UNE CLÉ PRIMAIRE est également un index - elle est fréquemment utilisée avec des champs ayant un attribut AUTO_INCREMENT. Ce type d'index n'accepte pas les valeurs NULL et une fois définies, les valeurs de la colonne qui a une PRIMARY KEY ne peuvent pas être modifiées.
-
UN INDEX DESCENDANT est un index qui stocke les lignes dans un ordre décroissant. Ce type d'index a été introduit dans MySQL 8.0 - MySQL utilisera ce type d'index lorsqu'un ordre décroissant est demandé par la requête.
Choisir les types de données optimaux pour les index dans MySQL
En ce qui concerne les index, il faut également garder à l'esprit que MySQL prend en charge une grande variété de types de données et que certains types de données ne peuvent pas être utilisés avec certains types d'index (par exemple, FULLTEXT les index ne peuvent être utilisés que sur des colonnes textuelles (CHAR, VARCHAR ou TEXT) - ils ne peuvent pas être utilisés sur d'autres types de données), donc avant de choisir les index pour la conception de votre base de données, décidez du type de données que vous allez utiliser sur la colonne en question (décidez quel type de classe de données vous allez stocker :allez-vous stocker des nombres ? Des valeurs de chaîne ? À la fois des nombres et des valeurs de chaîne ? etc.), puis décidez de la plage des valeurs que vous allez stocker (choisissez celui que vous ne pensez pas dépasser car l'augmentation de la plage de types de données peut être une tâche fastidieuse par la suite - nous vous recommandons d'opter pour un type de données simple), et si vous n'avez pas l'intention d'utiliser NULL valeurs dans vos colonnes, spécifiez vos champs comme NOT NULL chaque fois que vous le pouvez - lorsqu'un co nullable lumn est indexé, il nécessite un octet supplémentaire par entrée.
Choisir des jeux de caractères et des classements optimaux pour les index dans MySQL
Outre les types de données, gardez également à l'esprit que chaque caractère dans MySQL prend de la place. Par exemple, les caractères UTF-8 peuvent prendre entre 1 et 4 octets chacun, vous pouvez donc éviter d'indexer, par exemple, 255 caractères et n'utiliser, disons, que 50 ou 100 caractères pour une certaine colonne.
Les avantages et les inconvénients de l'utilisation des index dans MySQL
Le principal avantage de l'utilisation des index dans MySQL est l'augmentation des performances des requêtes de recherche correspondant à une clause WHERE - les index accélèrent les requêtes SELECT correspondant à une clause WHERE car MySQL ne lit pas toute la table pour trouver des lignes pertinent pour la requête. Cependant, gardez à l'esprit que les index ont leurs propres inconvénients. Les principaux sont les suivants :
-
Les index consomment de l'espace disque.
-
Les index dégradent les performances des requêtes INSERT, UPDATE et DELETE - lorsque les données sont mises à jour, l'index doit être mis à jour avec lui.
-
MySQL ne vous protège pas de l'utilisation simultanée de plusieurs types d'index. En d'autres termes, vous pouvez utiliser une CLÉ PRIMAIRE, un INDEX et un INDEX UNIQUE sur la même colonne - MySQL ne vous protège pas contre une telle erreur.
Si vous pensez que certaines de vos requêtes deviennent plus lentes, pensez à jeter un œil à l'onglet Query Monitor de ClusterControl - en activant le moniteur de requêtes, vous pouvez voir quand une certaine requête a été vue pour la dernière fois et son maximum et le temps d'exécution moyen qui peut vous aider à choisir les meilleurs index pour votre table.
Comment choisir le meilleur index à utiliser ?
Pour choisir le meilleur index à utiliser, vous pouvez utiliser les mécanismes intégrés de MySQL. Par exemple, vous pouvez utiliser l'explicateur de requête - la requête EXPLAIN. Il expliquera quelle table est utilisée, si elle a des partitions ou non, quels index sont possibles à utiliser et quelle clé (index) est utilisée. Il renverra également la longueur de l'index et le nombre de lignes renvoyées par votre requête :
mysql> EXPLAIN SELECT * FROM demo_table WHERE demo_field = ‘demo’\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: demo_table
partitions: NULL
type: ref
possible_keys: demo_field
key: demo_field
key_len: 1022
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
Dans ce cas, gardez à l'esprit que les index sont fréquemment utilisés pour aider MySQL à récupérer efficacement les données lorsque les ensembles de données sont plus volumineux que d'habitude. Si votre table est petite, vous n'aurez peut-être pas besoin d'utiliser des index, mais si vous voyez que vos tables deviennent de plus en plus grandes, il y a de fortes chances que vous puissiez bénéficier d'un index.
Afin de choisir le meilleur index à utiliser pour votre scénario spécifique, gardez à l'esprit que les index peuvent également être une cause majeure de problèmes de performances. Gardez à l'esprit que l'utilisation efficace ou non des index par MySQL dépend de plusieurs facteurs, notamment la conception de vos requêtes, les index utilisés, les types d'index utilisés, ainsi que la charge de votre base de données au moment où la requête est exécutée et autres choses. Voici quelques éléments à prendre en compte lors de l'utilisation d'index dans MySQL :
-
De combien de données disposez-vous ? Certaines d'entre elles sont peut-être redondantes ?
-
Quelles requêtes utilisez-vous ? Vos requêtes utiliseraient-elles des clauses LIKE ? Qu'en est-il de la commande ?
-
Quel type d'index auriez-vous besoin d'utiliser pour améliorer les performances de vos requêtes ?
-
Vos index seraient-ils grands ou petits ? Auriez-vous besoin d'utiliser un index sur un préfixe de la colonne pour réduire sa taille ?
Il convient de noter que vous devriez probablement éviter d'utiliser plusieurs types d'index (par exemple, un index B-Tree, un INDEX UNIQUE et une CLÉ PRIMAIRE) sur la même colonne également.
Améliorer les performances des requêtes avec les index
Pour améliorer les performances des requêtes avec les index, vous devez examiner vos requêtes - l'instruction EXPLAIN peut vous aider. En général, voici quelques éléments à prendre en compte si vous souhaitez que vos index améliorent les performances de vos requêtes :
-
Demandez uniquement à la base de données ce dont vous avez besoin. Dans la plupart des cas, l'utilisation de la colonne SELECT sera plus rapide que l'utilisation de SELECT * (c'est le cas sans utiliser les index également)
-
Un index B-tree peut convenir si vous recherchez des valeurs exactes (par exemple SELECT * FROM demo_table WHERE some_field ='x') ou si vous souhaitez rechercher des valeurs à l'aide de caractères génériques (par exemple, SELECT * FROM demo_table WHERE some_field LIKE 'demo%' - dans ce cas, gardez à l'esprit que l'utilisation de requêtes LIKE avec n'importe quoi au début pourrait faire plus de mal que de bien - évitez d'utiliser des requêtes LIKE avec un signe de pourcentage devant le texte que vous recherchez - de cette façon, MySQL pourrait ne pas utiliser d'index car il ne sait pas par quoi commence la valeur de la ligne) - mais gardez à l'esprit qu'un index B-tree peut également être utilisé pour les comparaisons de colonnes dans les expressions qui utilisent égal (=), supérieur à (>), supérieur ou égal à (>=), inférieur à (<), inférieur ou égal à (<=) ou BETWEEN opérateurs.
-
Un index FULLTEXT peut convenir si vous utilisez le texte intégral (MATCH ... AGAINST( )) requêtes de recherche ou si votre base de données est conçue de manière à n'utiliser que des colonnes textuelles - les index FULLTEXT peuvent utiliser des colonnes TEXT, CHAR ou VARCHAR, ils ne peuvent pas être utilisés sur d'autres types de colonnes.
-
Un index de couverture peut être utile si vous souhaitez exécuter des requêtes sans lectures d'E/S supplémentaires sur de grandes tables . Pour créer un index couvrant, couvrez les clauses WHERE, GROUP BY et SELECT utilisées par la requête.
Nous examinerons plus en détail les types d'index dans les prochaines parties de cette série de blogs, mais en général, si vous utilisez des requêtes telles que SELECT * FROM demo_table WHERE some_field ='x' a B-tree INDEX peut être un ajustement, si vous utilisez des requêtes MATCH() AGAINST(), vous devriez probablement regarder dans un index FULLTEXT, si votre table a des valeurs de ligne très longues, vous devriez probablement chercher à indexer une partie de la colonne.
Combien d'index devriez-vous avoir ?
Si vous avez déjà utilisé des index pour améliorer les performances de vos requêtes SELECT, vous vous êtes probablement posé une question :combien d'index devriez-vous réellement avoir ? Pour comprendre cela, vous devez garder à l'esprit les éléments suivants :
-
Les index sont généralement les plus efficaces avec de grandes quantités de données.
-
MySQL utilise un seul index pour chaque instruction SELECT dans une requête (les sous-requêtes sont vues comme des instructions séparées) - use la requête EXPLAIN pour savoir quels index sont les plus efficaces pour les requêtes que vous utilisez.
-
Les index doivent rendre toutes vos instructions SELECT assez rapides sans trop compromettre l'espace disque - "assez vite" , cependant, est relatif, vous devrez donc expérimenter.
Index et moteurs de stockage
Lorsque vous traitez avec des index dans MySQL, gardez également à l'esprit qu'il peut y avoir certaines sortes de limitations si vous utilisez différents moteurs (par exemple si vous utilisez MyISAM par opposition à InnoDB). Nous entrerons plus en détail dans un blog séparé, mais voici quelques idées :
-
Le nombre maximum d'index par tables MyISAM et InnoDB est de 64, le nombre maximum de colonnes par index dans les deux moteurs de stockage est de 16.
-
La longueur de clé maximale pour InnoDB est de 3 500 octets - la longueur de clé maximale pour MyISAM est de 1 000 octets.
-
Les index de texte intégral ont des limitations dans certains moteurs de stockage - par exemple, les index de texte intégral InnoDB ont 36 mots vides, MyISAM La liste des mots vides est un peu plus grande avec 143 mots vides. InnoDB dérive ces mots vides de la variable innodb_ft_server_stopword_table tandis que MyISAM dérive ces mots vides du fichier storage/myisam/ft_static.c - tous les mots trouvés dans le fichier seront traités comme des mots vides.
-
MyISAM était le seul moteur de stockage prenant en charge les options de recherche en texte intégral jusqu'à MySQL 5.6 (MySQL 5.6. 4 pour être exact) est apparu, ce qui signifie qu'InnoDB prend en charge les index de texte intégral depuis MySQL 5.6.4. Lorsqu'un index FULLTEXT est utilisé, il trouve des mots-clés dans le texte au lieu de comparer directement les valeurs aux valeurs de l'index.
-
Les index jouent un rôle très important pour InnoDB - InnoDB verrouille les lignes lorsqu'il y accède, donc un nombre réduit de les accès aux lignes InnoDB peuvent réduire les verrous.
-
MySQL vous permet d'utiliser des index en double sur la même colonne.
-
Certains moteurs de stockage ont certains types d'index par défaut (par exemple, pour le moteur de stockage MEMORY, le type d'index par défaut est hash )
Résumé
Dans cette partie sur les index dans MySQL, nous avons passé en revue certaines choses générales liées aux index dans ce système de gestion de base de données relationnelle. Dans les prochains articles de blog, nous passerons en revue des scénarios plus approfondis d'utilisation d'index dans MySQL, y compris l'utilisation d'index dans certains moteurs de stockage, etc. - nous expliquerons également comment ClusterControl peut être utilisé pour atteindre vos objectifs de performances dans MySQL.