La première chose que vous devez savoir est que les index sont un moyen d'éviter d'analyser la table complète pour obtenir le résultat que vous recherchez.
Il existe différents types d'index et ils sont implémentés dans la couche de stockage, il n'y a donc pas de norme entre eux et ils dépendent également du moteur de stockage que vous utilisez.
InnoDB et l'indice B + Tree
Pour InnoDB, le type d'index le plus courant est l'index B + Tree, qui stocke les éléments dans un ordre trié. De plus, vous n'avez pas besoin d'accéder à la vraie table pour obtenir les valeurs indexées, ce qui accélère considérablement le retour de votre requête.
Le "problème" de ce type d'index est que vous devez rechercher la valeur la plus à gauche pour utiliser l'index. Par conséquent, si votre index comporte deux colonnes, par exemple nom_prénom et prénom, l'ordre dans lequel vous interrogez ces champs est très important .
Donc, étant donné le tableau suivant:
CREATE TABLE person (
last_name VARCHAR(50) NOT NULL,
first_name VARCHAR(50) NOT NULL,
INDEX (last_name, first_name)
);
Cette requête profiterait de l'index:
SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"
Mais le suivant ne serait pas
SELECT last_name, first_name FROM person WHERE first_name = "Constantine"
Parce que vous interrogez la first_name
colonne en premier et que ce n'est pas la colonne la plus à gauche de l'index.
Ce dernier exemple est encore pire:
SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"
Parce que maintenant, vous comparez la partie la plus à droite du champ le plus à droite dans l'index.
L'index de hachage
Il s'agit d'un type d'index différent que, malheureusement, seul le backend mémoire prend en charge. Il est rapide comme l'éclair mais utile uniquement pour les recherches complètes, ce qui signifie que vous ne pouvez pas l'utiliser pour des opérations telles que >
, <
ou LIKE
.
Comme il ne fonctionne que pour le backend mémoire, vous ne l'utiliserez probablement pas très souvent. Le cas principal auquel je peux penser en ce moment est celui où vous créez une table temporaire dans la mémoire avec un ensemble de résultats d'une autre sélection et effectuez beaucoup d'autres sélections dans cette table temporaire en utilisant des index de hachage.
Si vous avez un grand VARCHAR
champ, vous pouvez "émuler" l'utilisation d'un index de hachage lorsque vous utilisez un arbre B, en créant une autre colonne et en y enregistrant un hachage de grande valeur. Disons que vous stockez une URL dans un champ et que les valeurs sont assez grandes. Vous pouvez également créer un champ entier appelé url_hash
et utiliser une fonction de hachage comme CRC32
ou toute autre fonction de hachage pour hacher l'URL lors de son insertion. Et puis, lorsque vous devez rechercher cette valeur, vous pouvez faire quelque chose comme ceci:
SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");
Le problème avec l'exemple ci-dessus est que, puisque la CRC32
fonction génère un hachage assez petit, vous vous retrouverez avec beaucoup de collisions dans les valeurs hachées. Si vous avez besoin de valeurs exactes, vous pouvez résoudre ce problème en procédant comme suit:
SELECT url FROM url_table
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";
Il vaut toujours la peine de hacher les choses même si le nombre de collisions est élevé, car vous n'effectuerez que la deuxième comparaison (la chaîne) avec les hachages répétés.
Malheureusement, en utilisant cette technique, vous devez toujours frapper la table pour comparer le url
champ.
Emballer
Quelques faits que vous pouvez considérer chaque fois que vous souhaitez parler d'optimisation:
La comparaison d'entiers est bien plus rapide que la comparaison de chaînes. Il peut être illustré par l'exemple de l'émulation de l'indice de hachage dans InnoDB
.
Peut-être que l'ajout d'étapes supplémentaires dans un processus le rend plus rapide et non plus lent. Cela peut être illustré par le fait que vous pouvez optimiser un SELECT
en le divisant en deux étapes, en faisant que la première stocke des valeurs dans une table en mémoire nouvellement créée, puis en exécutant les requêtes plus lourdes sur cette deuxième table.
MySQL a aussi d'autres index, mais je pense que l'arbre B + est le plus utilisé de tous les temps et celui de hachage est une bonne chose à savoir, mais vous pouvez trouver les autres dans la documentation MySQL .
Je vous recommande fortement de lire le livre "High Performance MySQL", la réponse ci-dessus était définitivement basée sur son chapitre sur les index.