• Aucun résultat trouvé

2.10 Suppression et modification de données

3.1.1 Qu’est-ce qu’un index ?

Structure de données qui reprend la liste ordonnée des valeurs auxquelles il se rap-

porte. Source : Définition

Lorsque vous créez un index sur une table, MySQL stocke cet index sous forme d’une structure particulière, contenant les valeurs des colonnes impliquées dans l’index. Cette structure stocke les valeurs triées et permet d’accéder à chacune de manière efficace et rapide. Petit schéma expli- catif dans le cas d’un index sur l’idde la tableAnimal(je ne prends que les neuf premières lignes pour ne pas surcharger).

[[attention]] | Pour permettre une compréhension plus facile, je représente ici l’index sous forme de table. En réalité, par défaut, MySQL stocke les index dans une structure de type “arbre” (l’index est alors de typeBTREE). Le principe est cependant le même.

Les données d’Animalne sont pas stockées suivant un ordre intelligible pour nous. Par contre, l’index sur l’idest trié simplement par ordre croissant. Cela permet de grandement accélérer toute recherche faite sur cetid.

3.1 Index

Figure 3.1 – Index sur l’id

Imaginons en effet, que nous voulions récupérer toutes les lignes dont l’idest inférieur ou égal à 5. Sans index, MyQSL doit parcourir toutes les lignes une à une. Par contre, grâce à l’index, dès qu’il tombe sur la ligne dont l’idest 6, il sait qu’il peut s’arrêter, puisque toutes les lignes suivantes au- ront unidsupérieur ou égal à 6. Dans cet exemple, on ne gagne que quelques lignes, mais imaginez une table contenant des milliers de lignes. Le gain de temps peut être assez considérable. Par ailleurs, avec lesidtriés par ordre croissant, pour rechercher unidparticulier, MySQL n’est pas obligé de simplement parcourir les données ligne par ligne. Il peut utiliser des algorithmes de recherche puissants (comme la recherche dichotomique), toujours afin d’accélérer la recherche. Mais pourquoi ne pas simplement trier la table complète sur la base de la colonneid? Pourquoi créer et stocker une structure spécialement pour l’index ? Tout simplement parce qu’il peut y avoir plusieurs index sur une même table, et que l’ordre des lignes pour chacun de ces index n’est pas nécessairement le même. Par exemple, nous pouvons créer un second index pour notre table Animal, sur la colonnedate_naissance.

Comme vous pouvez le voir, l’ordre n’est pas du tout le même.

3.1.1.1 Intérêt des index

Vous devriez avoir compris maintenant que tout l’intérêt des index est d’accélérer les requêtes qui utilisent des colonnes indexées comme critères de recherche. Par conséquent, si vous savez que dans votre application, vous ferez énormément de recherches sur la colonneX, ajoutez donc un index sur cette colonne, vous ne vous en porterez que mieux.

Les index permettent aussi d’assurer l’intégrité des données de la base. Pour cela, il existe en fait plusieurs types d’index différents, et deux types de “clés”. Lorsque je parle de garantir l’intégrité de vos données, cela signifie en gros garantir la qualité de vos données, vous assurer que vos

Figure 3.2 – Index sur id et date_naissance

données ont du sens. Par exemple, soyez sûrs que vous ne faites pas référence à un client dans la tableCommande, alors qu’en réalité, ce client n’existe absolument pas dans la tableClient.

3.1.1.2 Désavantages

Si tout ce que fait un index, c’est accélérer les requêtes utilisant des critères de recherche cor- respondants, autant en mettre partout, et en profiter à chaque requête ! Sauf qu’évidemment, ce n’est pas si simple, les index ont deux inconvénients.

— Ils prennent de la place en mémoire

— Ils ralentissent les requêtes d’insertion, modification et suppression, puisqu’à chaque fois, il faut remettre l’index à jour en plus de la table.

Par conséquent, n’ajoutez pas d’index lorsque ce n’est pas vraiment utile.

3.1.1.3 Index sur plusieurs colonnes

Reprenons l’exemple d’une table appeléeClient, qui reprend les informations des clients d’une société. Elle se présente comme suit :

id nom prenom init_2e_prenom email

1 Dupont Charles T charles.dupont@email.com

2 François Damien V fdamien@email.com

3 Vandenbush Guillaume A guillaumevdb@email.com

4 Dupont Valérie C valdup@email.com

5 Dupont Valérie G dupont.valerie@email.com

6 François Martin D mdmartin@email.com

7 Caramou Arthur B leroiarthur@email.com

8 Boulian Gérard M gebou@email.com

9 Loupiot Laura F loulau@email.com

10 Sunna Christine I chrichrisun@email.com

Vous avez bien sûr un index sur la colonneid, mais vous constatez que vous faites énormément de recherches par nom, prénom et initiale du second prénom. Vous pourriez donc faire trois in- dex, un pour chacune de ces colonnes. Mais, si vous faites souvent des recherches sur les trois colonnes à la fois, il vaut encore mieux faire un seul index, sur les trois colonnes (nom, prenom, init_2e_prenom). L’index contiendra donc les valeurs des trois colonnes et sera trié par nom, en- suite par prénom, et enfin par initiale (l’ordre des colonnes a donc de l’importance !).

Du coup, lorsque vous cherchez “Dupont Valérie C.”, grâce à l’index MySQL trouvera rapidement tous les “Dupont”, parmi lesquels il trouvera toutes les “Valérie” (toujours en se servant du même index), parmi lesquelles il trouvera celle (ou celles) dont le second prénom commence par “C”.

3.1.1.3.1 Tirer parti des “index par la gauche”

Tout ça c’est bien beau si on fait souvent 80

3.1 Index

Figure 3.3 – Index sur trois colonnes de recherche ?

Hé bien non ! MySQl est beaucoup trop fort : il est capable de tirer parti de votre index sur (nom, prenom, init_2e_prenom) pour certaines autres recherches. En effet, si l’on représente les index sous forme de tables, voici ce que cela donnerait pour les quatre index (prenom), (nom), (nom, prenom) et (nom, prenom, init_2e_prenom).

Figure 3.4 – Index par la gauche [[question]] | Remarquez-vous quelque chose d’intéressant ?

Oui ! Bien vu ! L’index (nom, prenom) correspond exactement aux deux premières colonnes de l’in- dex (nom, prenom, init_2e_prenom) ; pas seulement au niveau des valeurs mais surtout au niveau de l’ordre. Et l’index (nom) correspond à la première colonne de l’index (nom, prenom, init_2e_prenom). Or, je vous ai dit que lorsque vous faites une recherche sur le nom, le prénom et l’initiale avec

l’index (nom, prenom, init_2e_prenom), MySQL regarde d’abord le nom, puis le prénom, et pour finir l’initiale. Donc, si vous ne faites une recherche que sur le nom et le prénom, MySQL va intelli- gemment utiliser l’index (nom, prenom, init_2e_prenom) : il va simplement laisser tomber l’étape de l’initiale du second prénom. Idem si vous faites une recherche sur le nom : MySQL se basera uniquement sur la première colonne de l’index existant.

Par conséquent, pas besoin de définir un index (nom, prenom) ou un index (nom). Ils sont en quelque sorte déjà présents.

Mais qu’en est-il des index (prenom), ou (prenom, init_2e_prenom) ? Vous pouvez voir que la table contenant l’index (prenom) ne correspond à aucune colonne d’un index existant (au niveau de l’ordre des lignes). Par conséquent, si vous voulez un index sur (prenom), il vous faut le créer. Même chose pour (prenom, init_2e_prenom) ou (nom, init_2e_prenom).

Figure 3.5 – Index par la gauche

On parle d’index “par la gauche”. Donc si l’on prend des sous-parties d’index existant en prenant des colonnes “par la gauche”, ces index existent. Mais si l’on commence par la droite ou que l’on “saute” une colonne, ils n’existent pas et doivent éventuellement être créés.

3.1.1.4 Index sur des colonnes de type alphanumérique

3.1.1.4.1 Types CHAR et VARCHAR

Lorsque l’on indexe une colonne de typeVARCHAR

ouCHAR(comme la colonnenomde la tableClientpar exemple), on peut décomposer l’index de la manière suivante : 1e lettre 2e lettre 3e lettre 4e lettre 5e lettre 6e lettre 7e lettre 8e lettre 9e lettre 10e lettre B o u l i a n C a r a m o u D u p o n t D u p o n t D u p o n t F r a n ç o i s F r a n ç o i s L o u p i o t S u n n a V a n d e n b u s h

3.1 Index nom Boulian Caramou Dupont Dupont Dupont François François Loupiot Sunna Vandenbush

[[question]] | En quoi cela nous intéresse-t-il ?

C’est très simple. Ici, nous n’avons que des noms assez courts. La colonnenompeut par exemple être de typeVARCHAR(30). Mais imaginez une colonne de typeVARCHAR(150), qui contient des titres de livres par exemple. Si l’on met un index dessus, MySQL va indexer jusqu’à 150 caractères. Or, il est fort probable que les 25-30 premiers caractères du titre suffisent à trier ceux-ci. Au pire, un ou deux ne seront pas exactement à la bonne place, mais les requêtes en seraient déjà grandement accélérées.

Il serait donc plutôt pratique de dire à MySQL : “Indexe cette colonne, mais base-toi seulement sur lesxpremiers caractères”. Et c’est possible évidemment (sinon je ne vous en parlerais pas :p ), et c’est même très simple. Lorsque l’on créera l’index sur la colonnetitre_livre, il suffira d’indiquer un nombre entre parenthèses :titre_livre(25)par exemple. Ce nombre étant bien sûr le nombre de caractères (dans le sens de la lecture, donc à partir de la gauche) à prendre en compte pour l’index. Le fait d’utiliser ces index partiels sur des champs alphanumériques permet de gagner de la place (un index sur 150 lettres prend évidemment plus de place qu’un index sur 20 lettres), et si la longueur est intelligemment définie, l’accélération permise par l’index sera la même que si l’on avait pris la colonne entière.

3.1.1.4.2 Types BLOB et TEXT (et dérivés)

Si vous mettez un index sur une colonne de typeBLOBouTEXT (ou un de leurs dérivés), MySQL exige que vous précisiez un nombre de caractères à prendre en compte. Et heureusement… Vu la longueur potentielle de ce que l’on stocke dans de telles colonnes.