26 jul 2012

Optimización de MySQL (Parte 1)

Las bases de datos crecen y crecen a lo largo del tiempo, cada día almacenan más y más información. Por lo que es necesario asegurarse que los resultados solicitados sean entregados en el menor tiempo posible.

Medio segundo puede significar la perdida de un 20% del tráfico del sitio, así que es muy importante mejorar el rendimiento de las bases de datos.

Se pueden usar índices y particiones para limitar la cantidad de registros que MySQL tiene que procesar para entregar un resultado.

Para una consulta frecuente, la creación de un índice es la mejor manera de acelerar las cosas. Por ejemplo, si tenemos una tabla con 40 columnas, de las cuales una columna es accesada frecuentemente, se puede crear un índice para dicha columna y acelerar el proceso de búsqueda. Si no existen índices, MySQL hará un "escaneo" completo para obtener los datos, es decir, se examinan todos los registros en la tabla, uno a uno, hasta el último registro o se satisfaga la consulta.

En otros términos, podemos pensar en el índice de un libro. Maravilloso, no?

Cuando creamos un índice para un campo, MySQL registra toda la información de la columna en particular, la ordena y luego la almacena en un objeto único o archivo, separado de la tabla, junto con referencias a la tabla original con los datos sin ordenar.

El mantenimiento de los índices no requiere cosas adicionales. Si creamos un índice para tabla que es actualizada con frecuencia, todos los DELETEINSERT o UPDATE también serán actualizados en el índice.

Cuidado, el manejo incorrecto de los índices ocasionará una carga extra al servidor y puede generar lentitud en otros procesos, por lo que no deben crear índices para todos los campos. Sólo creen índices para las consultas mas frecuentes o para tablas muy grandes (con miles y miles de registros)

Ahora, la forma de indexar va a depender del engine (motor de almacenamiento) que hayan usando al momento de crear las tablas de la base de datos. Anteriomente, MyISAM era el engine por default en mysql server, pero a partir de la versión 5.5 InnoDB a tomado su lugar. Pero no se preocupen, esto es algo que se puede manipular en el archivo de configuración (my.cnf) o se puede especificar mientras se crean las tablas.

Hay varios tipos de índices que se pueden utilizar, tales como B-Tree o Hash . La elección del índice depende del motor de almacenamiento que esté en uso.

UTILIZAR INDICES

Se puede crear un índice para una tabla (mientras se crea la tabla), o bien crearlo para las tablas existentes. Por ejemplo:

CREATE TABLE records (
     name VARCHAR(50),
     age INT,
     id_num INT, INDEX (id)
         );

Esto crea un índice llamada id para la columna id_num. Para una tabla existente el comando podría ser:

CREATE INDEX id ON records(id_num);

Para crear múltiples índices para una tabla:

ALTER TABLE records ADD INDEX id(id_num), ADD INDEX name(name);

Como MySQL desconoce la naturaleza exacta de los datos almacenados en un campo, se creará un índice con toda la longitud de los datos. Por lo tanto, si tenemos una tabla de artículos, y crear un índice en el campo de título de 50 caracteres, MySQL almacena la longitud total del nombre de cada artículo en la base de datos. En un caso como éste, es sabio almacenar sólo los primeros 20 caracteres en el índice, en lugar de la longitud total. Para grandes bases de datos con columnas muy largas, sería un desperdicio de espacio almacenar todo el nombre en el índice.

Puede limitar la longitud de los datos a 20 caracteres especificandolo junto con el nombre de la columna, de este modo:

ALTER TABLE records ADD INDEX id(id_num), ADD INDEX name(name(20));

Recuerden que un índice mal creado puede ocasionar un consumo excesivo de los recursos del servidor, sobre todo si se usa InnoDB.

En el próximo post hablaremos de las particiones.