Índices y optimización de consultas

Hacer que una consulta trabaje es una cosa, pero obtener una consulta que trabaje lo más rápidamente es otra muy diferente. Podemos acelerar nuestras consultas de dos maneras básicamente, una de ellas es afinando nuestro servidor para que responda lo mejor posible, y la otra, que es la que trataremos en este artículo, es haciendo uso de los índices de una manera inteligente.

Los índices son usados para encontrar rápidamente los registros que tengan un determinado valor en alguna de sus columnas. Sin un índice, MySQL tiene que iniciar con el primer registro y leer a través de toda la tabla para encontrar los registros relevantes. Aún en tablas pequeñas, de unos 1000 registros, es por lo menos 100 veces más rápido leer los datos usando un índice, que haciendo una lectura secuencial.

Cuando MySQL trata de responder una consulta, examina una variedad de estadísticas acerca de nuestros datos y decide como buscar los datos que deseamos de la manera más rápida. Sin embargo, como se acaba de mencionar, cuando en una tabla no existen índices en los cuales pueda auxiliarse MySQL para resolver una consulta se tendrán que leer todos los registros de la tabla de manera secuencial. Esto es comúnmente llamado un "escaneo completo de una tabla", y es muchas veces algo que se debe evitar.

En particular, debemos evitar las escaneos completos de tablas por las siguientes razones:

  • Sobrecarga de CPU. El proceso de checar cada uno de los registros en una tabla es insignificante cuando se tienen pocos datos, pero puede convertirse en un problema a medida que va aumentando la cantidad de registros en nuestra tabla. Existe una relación proporcional entre el número de registros que tiene una tabla y la cantidad de tiempo que le toma a MySQL revisarla completamente.
  • Concurrencia. Mientras MySQL está leyendo los datos de una tabla, éste la bloquea, de tal manera que nadie más puede escribir en ella, aunque si pueden leerla. Cuando MySQL está actualizando o eliminando filas de una tabla, éste la bloquea, y por lo tanto nadie puede al menos leerla.
  • Sobrecarga de disco. En una tabla muy grande, un escaneo completo consume una gran cantidad de entrada/salida en el disco. Esto puede alentar siginificativamente nuestro servidor de bases de datos, especialmente si tenemos un disco IDE algo antiguo.

En resumen, lo mejor es tratar de que los escaneos completos de tablas sean mínimos -- especialmente si nuestra aplicación necesita escalabilidad en tamaño, número de usuarios, o ambos. Las versiones actuales de MySQL hacen distintas mejoras en cuanto a concurrencia, pero ese tema está más allá de nuestra discusión.

Es en estos casos donde la indexación puede ayudarnos. De manera simple, un índice le permite a MySQL determinar si un valor dado coincide con cualquier fila en una tabla.

Cuando indexamos una columna en particular, MySQL crea otra estructura de datos (un índice) que usa para almacenar información extra acerca de los valores en la columna indexada. Los valores indexados son llamados frecuentemente claves. Aunque esta es la manera simple de explicar los índices, realmente es un poco más complejo, ya que MySQL almacena todas las claves del índice en una estructura de datos de árbol. Esta estructura de datos de árbol le permite a MySQL encontrar claves muy rápidamente.

Cuando MySQL encuentre que hay un índice en una columna, lo usará en vez de hacer un escaneo completo de la tabla. Esto reduce de manera imporante los tiempos de CPU y las operaciones de entrada/salida en disco, a su vez que se mejora la concurrencia porque MySQL bloqueará la tabla únicamente para obtener las filas que necesite (en base a lo que encontró en el índice). Cuando tenemos grandes cantidades de datos en nuestras tablas, la mejora en la obtención de los datos puede ser muy significativa.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.