¿Por qué es necesario?
Cuando los datos se almacenan en dispositivos de almacenamiento basados en disco, se almacenan como bloques de datos. Se accede a estos bloques en su totalidad, lo que los convierte en la operación de acceso al disco atómico. Los bloques de disco están estructurados de manera muy similar a las listas enlazadas; ambos contienen una sección para datos, un puntero a la ubicación del siguiente nodo (o bloque), y ambos no necesitan almacenarse de manera contigua.
Debido al hecho de que una cantidad de registros solo se puede ordenar en un campo, podemos afirmar que la búsqueda en un campo que no está ordenado requiere una Búsqueda lineal que requiere N/2
accesos de bloque (en promedio), donde N
es la cantidad de bloques que La mesa se extiende. Si ese campo es un campo sin clave (es decir, no contiene entradas únicas), se debe buscar en todo el espacio de tabla en los N
accesos de bloque.
Mientras que con un campo ordenado, se puede utilizar una búsqueda binaria, que tiene log2 N
accesos de bloque. Además, dado que los datos se ordenan dado un campo sin clave, no es necesario buscar valores duplicados en el resto de la tabla una vez que se encuentra un valor más alto. Por lo tanto, el aumento del rendimiento es sustancial.
¿Qué es la indexación?
La indexación es una forma de ordenar una serie de registros en múltiples campos. Crear un índice en un campo en una tabla crea otra estructura de datos que contiene el valor del campo y un puntero al registro con el que se relaciona. Esta estructura de índice se ordena, permitiendo que se realicen búsquedas binarias en ella.
La desventaja de la indexación es que estos índices requieren espacio adicional en el disco ya que los índices se almacenan juntos en una tabla usando el motor MyISAM, este archivo puede alcanzar rápidamente los límites de tamaño del sistema de archivos subyacente si se indexan muchos campos dentro de la misma tabla .
¿Como funciona?
En primer lugar, describamos un esquema de tabla de base de datos de muestra;
Nombre del campo Tipo de datos Tamaño en el disco
id (clave principal) INT sin signo 4 bytes
firstName Char (50) 50 bytes
lastName Char (50) 50 bytes
emailAddress Char (100) 100 bytes
Nota : se usó char en lugar de varchar para permitir un tamaño preciso en el valor del disco. Esta base de datos de muestra contiene cinco millones de filas y no está indexada. Ahora se analizará el rendimiento de varias consultas. Estos son una consulta mediante la identificación y uno (un campo clave ordenados) utilizando el primerNombre (sin ordenar un campo que no son clave).
Ejemplo 1 - campos ordenados vs no clasificados
Dada nuestra base de datos de muestra de r = 5,000,000
registros de un tamaño fijo que proporciona una longitud de registro de R = 204
bytes y se almacenan en una tabla utilizando el motor MyISAM que utiliza los B = 1,024
bytes de tamaño de bloque predeterminados . El factor de bloqueo de la tabla serían los bfr = (B/R) = 1024/204 = 5
registros por bloque de disco. El número total de bloques necesarios para mantener la mesa es N = (r/bfr) = 5000000/5 = 1,000,000
bloques.
Una búsqueda lineal en el campo de identificación requeriría un promedio de N/2 = 500,000
accesos de bloque para encontrar un valor, dado que el campo de identificación es un campo clave. Pero como el campo de identificación también está ordenado, se puede realizar una búsqueda binaria que requiere un promedio de log2 1000000 = 19.93 = 20
accesos de bloque. Al instante podemos ver que esto es una mejora drástica.
Ahora el campo firstName no está ordenado ni es un campo clave, por lo que una búsqueda binaria es imposible, ni los valores son únicos, por lo que la tabla requerirá buscar hasta el final los N = 1,000,000
accesos de un bloque exacto . Es esta situación que la indexación pretende corregir.
Dado que un registro de índice contiene solo el campo indexado y un puntero al registro original, es lógico pensar que será más pequeño que el registro de campo múltiple al que apunta. Por lo tanto, el índice en sí mismo requiere menos bloques de disco que la tabla original, lo que, por lo tanto, requiere menos accesos de bloque para iterar. El esquema para un índice en el campo firstName se describe a continuación;
Nombre del campo Tipo de datos Tamaño en el disco
firstName Char (50) 50 bytes
(puntero de registro) Especial 4 bytes
Nota : Los punteros en MySQL tienen una longitud de 2, 3, 4 o 5 bytes, dependiendo del tamaño de la tabla.
Ejemplo 2 - indexación
Dada nuestra base de datos de muestra de r = 5,000,000
registros con una longitud de registro de R = 54
bytes de índice y utilizando los B = 1,024
bytes de tamaño de bloque predeterminado . El factor de bloqueo del índice serían los bfr = (B/R) = 1024/54 = 18
registros por bloque de disco. El número total de bloques necesarios para mantener el índice es N = (r/bfr) = 5000000/18 = 277,778
bloques.
Ahora, una búsqueda con el campo firstName puede utilizar el índice para aumentar el rendimiento. Esto permite una búsqueda binaria del índice con un promedio de log2 277778 = 18.08 = 19
accesos de bloque. Para encontrar la dirección del registro real, que requiere un acceso de bloque adicional para leer, llevando el total para 19 + 1 = 20
bloquear los accesos, muy lejos de los 1,000,000 de accesos de bloque requeridos para encontrar una coincidencia de FirstName en la tabla no indexada.
¿Cuándo debería usarse?
Dado que la creación de un índice requiere espacio en disco adicional (277,778 bloques adicionales del ejemplo anterior, un aumento de ~ 28%), y que demasiados índices pueden causar problemas derivados de los límites de tamaño del sistema de archivos, se debe pensar cuidadosamente para seleccionar el correcto campos para indexar.
Dado que los índices solo se usan para acelerar la búsqueda de un campo coincidente dentro de los registros, es lógico que los campos de indexación utilizados solo para la salida sean simplemente una pérdida de espacio en disco y tiempo de procesamiento al realizar una operación de inserción o eliminación, y por lo tanto debería ser evitado. También dada la naturaleza de una búsqueda binaria, la cardinalidad o unicidad de los datos es importante. La indexación en un campo con una cardinalidad de 2 dividiría los datos a la mitad, mientras que una cardinalidad de 1,000 devolvería aproximadamente 1,000 registros. Con una cardinalidad tan baja, la efectividad se reduce a una clasificación lineal, y el optimizador de consultas evitará usar el índice si la cardinalidad es inferior al 30% del número de registro, lo que hace que el índice sea una pérdida de espacio.