Deshabilita MySQL indexación de un valor total de BLOB
, TEXT
y las largas VARCHAR
columnas porque los datos que contienen pueden ser enormes, e implícitamente índice DB serán grandes, es decir, ningún beneficio de índice.
MySQL requiere que defina los primeros N caracteres a indexar, y el truco consiste en elegir un número N que sea lo suficientemente largo como para proporcionar una buena selectividad, pero lo suficientemente corto como para ahorrar espacio. El prefijo debe ser lo suficientemente largo como para que el índice sea casi tan útil como lo sería si indexara toda la columna.
Antes de continuar, definamos algunos términos importantes. La selectividad del índice es la relación del total de valores indexados distintos y el número total de filas . Aquí hay un ejemplo para la tabla de prueba:
+-----+-----------+
| id | value |
+-----+-----------+
| 1 | abc |
| 2 | abd |
| 3 | adg |
+-----+-----------+
Si indexamos solo el primer carácter (N = 1), la tabla de índice se verá como la siguiente tabla:
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| a | 1,2,3 |
+---------------+-----------+
En este caso, la selectividad del índice es igual a IS = 1/3 = 0.33.
Veamos ahora qué sucederá si aumentamos el número de caracteres indexados a dos (N = 2).
+---------------+-----------+
| indexedValue | rows |
+---------------+-----------+
| ab | 1,2 |
| ad | 3 |
+---------------+-----------+
En este escenario IS = 2/3 = 0.66, lo que significa que aumentamos la selectividad del índice, pero también hemos aumentado el tamaño del índice. El truco consiste en encontrar el número mínimo N que dará como resultado una selectividad de índice máxima .
Hay dos enfoques que puede hacer cálculos para su tabla de base de datos. Haré una demostración en el volcado de esta base de datos .
Supongamos que queremos agregar la columna last_name en los empleados de la tabla al índice, y queremos definir el número N más pequeño que produzca la mejor selectividad del índice.
Primero identifiquemos los apellidos más frecuentes:
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)
Como puede ver, el apellido Baba es el más frecuente. Ahora vamos a encontrar los prefijos de apellido más frecuentes , comenzando con los prefijos de cinco letras.
+-----+--------+
| 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)
Hay muchos más casos de cada prefijo, lo que significa que tenemos que aumentar el número N hasta que los valores sean casi los mismos que en el ejemplo anterior.
Aquí están los resultados para 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 |
+-----+-----------+
Aquí están los resultados para 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)
Estos son muy buenos resultados. Esto significa que podemos hacer que el índice en la columna indexe last_name
solo los primeros 10 caracteres. En la tabla, la columna de definición last_name
se define como VARCHAR(16)
, y esto significa que hemos guardado 6 bytes (o más si hay caracteres UTF8 en el apellido) por entrada. En esta tabla hay 1637 valores distintos multiplicados por 6 bytes que son aproximadamente 9 KB, e imagine cómo crecería este número si nuestra tabla contiene millones de filas.
Puede leer otras formas de calcular el número de N en mis índices indexados en MySQL .
UNIQUE
claves?