L' indexation d' une valeur MySQL exclut du financement complet de BLOB
, TEXT
et de longues VARCHAR
colonnes parce que les données qu'elles contiennent peuvent être énormes, et implicitement l' indice DB sera grand, ce qui signifie aucun avantage de l' indice.
MySQL nécessite que vous définissiez les N premiers caractères à indexer, et l'astuce consiste à choisir un nombre N suffisamment long pour donner une bonne sélectivité, mais suffisamment court pour économiser de l'espace. Le préfixe doit être suffisamment long pour rendre l'index presque aussi utile qu'il le serait si vous aviez indexé la colonne entière.
Avant d'aller plus loin, définissons quelques termes importants. La sélectivité d'index est le rapport du total des valeurs indexées distinctes et du nombre total de lignes . Voici un exemple de table de test:
+-----+-----------+
| id | value |
+-----+-----------+
| 1 | abc |
| 2 | abd |
| 3 | adg |
+-----+-----------+
Si nous indexons uniquement le premier caractère (N = 1), la table d'index ressemblera au tableau suivant:
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| a | 1,2,3 |
+---------------+-----------+
Dans ce cas, la sélectivité de l'indice est égale à IS = 1/3 = 0,33.
Voyons maintenant ce qui se passera si nous augmentons le nombre de caractères indexés à deux (N = 2).
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| ab | 1,2 |
| ad | 3 |
+---------------+-----------+
Dans ce scénario, IS = 2/3 = 0,66, ce qui signifie que nous avons augmenté la sélectivité de l'indice, mais nous avons également augmenté la taille de l'indice. L'astuce consiste à trouver le nombre minimal N qui se traduira par une sélectivité d'indice maximale .
Vous pouvez effectuer deux calculs pour votre table de base de données. Je ferai une démonstration sur le vidage de cette base de données .
Disons que nous voulons ajouter la colonne last_name dans les employés de la table à l'index, et nous voulons définir le plus petit nombre N qui produira la meilleure sélectivité d'index.
Identifions d'abord les noms de famille les plus fréquents:
select count(*) as cnt, last_name
from employees
group by employees.last_name
order by cnt
+-----+-------------+
| cnt | last_name |
+-----+-------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Farris |
| 222 | Sudbeck |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Neiman |
| 218 | Mandell |
| 218 | Masada |
| 217 | Boudaillier |
| 217 | Wendorf |
| 216 | Pettis |
| 216 | Solares |
| 216 | Mahnke |
+-----+-------------+
15 rows in set (0.64 sec)
Comme vous pouvez le voir, le nom de famille Baba est le plus fréquent. Nous allons maintenant trouver les préfixes last_name les plus fréquents , en commençant par les préfixes à cinq lettres.
+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa |
| 758 | Mande |
| 711 | Schwa |
| 562 | Angel |
| 561 | Gecse |
| 555 | Delgr |
| 550 | Berna |
| 547 | Peter |
| 543 | Cappe |
| 539 | Stran |
| 534 | Canna |
| 485 | Georg |
| 417 | Neima |
| 398 | Petti |
| 398 | Duclo |
+-----+--------+
15 rows in set (0.55 sec)
Il y a beaucoup plus d'occurrences de chaque préfixe, ce qui signifie que nous devons augmenter le nombre N jusqu'à ce que les valeurs soient presque les mêmes que dans l'exemple précédent.
Voici les résultats pour N = 9
select count(*) as cnt, left(last_name,9) as prefix
from employees
group by prefix
order by cnt desc
limit 0,15;
+-----+-----------+
| cnt | prefix |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudailli |
| 216 | Cummings |
| 216 | Pettis |
+-----+-----------+
Voici les résultats pour N = 10.
+-----+------------+
| cnt | prefix |
+-----+------------+
| 226 | Baba |
| 223 | Coorg |
| 223 | Gelosh |
| 222 | Sudbeck |
| 222 | Farris |
| 221 | Adachi |
| 220 | Osgood |
| 218 | Mandell |
| 218 | Neiman |
| 218 | Masada |
| 217 | Wendorf |
| 217 | Boudaillie |
| 216 | Cummings |
| 216 | Pettis |
| 216 | Solares |
+-----+------------+
15 rows in set (0.56 sec)
Ce sont de très bons résultats. Cela signifie que nous pouvons faire l'index sur la colonne last_name
en n'indexant que les 10 premiers caractères. Dans la colonne de définition de table last_name
est définie comme VARCHAR(16)
, et cela signifie que nous avons enregistré 6 octets (ou plus s'il y a des caractères UTF8 dans le nom de famille) par entrée. Dans ce tableau, il y a 1637 valeurs distinctes multipliées par 6 octets soit environ 9 Ko, et imaginez comment ce nombre augmenterait si notre tableau contient des millions de lignes.
Vous pouvez lire d'autres façons de calculer le nombre de N dans mes post index préfixés dans MySQL .
UNIQUE
clés?