Índices y optimización de consultas

Existen cuatro tipos de índices que podemos utilizar en MySQL; de clave primaria, únicos, de texto completo, y ordinarios. Cada uno de ellos será explicado a continuación.

. Índices de clave primaria

Una clave primaria es un índice sobre uno o más campos donde cada valor es único y ninguno de los valores son NULL.

Para crear un índice de clave primaria tenemos básicamente dos opciones:

  1. Crear el índice de clave primaria al momento de crear la tabla. En este caso se usa la opción PRIMARY KEY al final de la definición de los campos, con una lista de los campos que serán parte del índice.
    CREATE TABLE nombreTabla(campo1 tipoDato,
     [campo2...,] PRIMARY KEY (campo1 [,campo2...]) );

    Hacemos énfasis en que la palabra clave NOT NULL es obligatoria para un campo cuando éste vaya a formar parte de una clave primaria; como mencionamos anteriormente, las claves primarias no pueden contener valores nulos. Si intentamos crear una clave primaria sobre un campo nulo, MySQL nos marcará un error.

  2. Crear una clave primaria en una tabla existente con el uso del comando ALTER TABLE:
    ALTER TABLE nombreTabla ADD PRIMARY KEY(campo1 [,campo2...]);

Por ejemplo, suponiendo que ya tenemos en nuestro sistema una tabla que fue creada de la siguiente manera (sin clave primaria, y con el campo id aceptando valores NULL):

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos varchar(70));

Podemos crear una clave primaria sobre el campo id con esta sentencia:

ALTER TABLE usuarios MODIFY id INT NOT NULL, ADD PRIMARY KEY(id);

Para observar los cambios que hemos hecho, podemos examinar las columnas de la tabla usuarios con una sentencia DESCRIBE:

mysql> DESCRIBE usuarios;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int(11)     |      | PRI | 0       |       |
| nombre    | varchar(50) | YES  |     | NULL    |       |
| apellidos | varchar(70) | YES  |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

El campo id no tiene un valor YES en la columna Null, lo que indica que este campo ya no podrá almacenar valores nulos. Se puede observar también que se tiene un valor PRI en la columna Key, lo que indica que este campo es una clave primaria.

Las claves primarias pueden constar de más de un campo. Hay algunas veces en las que un solo campo no puede identificar de manera única a un registro.

. Índices ordinarios

Un índice que no es primario permite valores duplicados (a menos que los campos hayan sido especificados como UNIQUE).

Para crear un índice ordinario tenemos básicamente dos opciones:

  1. Podemos crear un índice ordinario al mismo tiempo que creamos la tabla con el uso de la opción INDEX.
    CREATE TABLE nombreTabla(campo1 tipoDato, campo2 tipoDato,..
      INDEX [nombreIndice] (campo1 [,campo2...]));
  2. De igual manera, podemos crear el índice con el uso de la sentencia ALTER TABLE si es que la tabla ya existe.
    ALTER TABLE nombreTabla ADD INDEX [nombreIndice] (campo1 [,campo2...]);

    También es posible usar la sentencia CREATE INDEX para crear un índice en una tabla existente.

    CREATE INDEX nombreIndice ON nombreTabla(campo1 [,campo2...]);

    Ambas sentencias piden el nombre del índice, sin embargo con la sentencia CREATE INDEX el nombre es obligatorio.

Por ejemplo, para la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos varchar(70));

Se puede crear un índice en la columna apellidos con una sentencia ALTER TABLE:

ALTER TABLE usuarios ADD INDEX idx_apellidos (apellidos);

O bien, con una sentencia CREATE INDEX:

CREATE INDEX idx_apellidos ON usuarios(apellidos);

. Índices de texto completo

Los índices de texto completo son del tipo FULLTEXT, se usan en tablas del tipo MyISAM, y pueden contener uno o más campos del tipo CHAR, VARCHAR y TEXT. Un índice de texto completo está diseñado para facilitar y optimizar la búsqueda de palabras clave en tablas que tienen grandes cantidades de información en campos de texto.

Para crear un índice de texto completo tenemos básicamente dos opciones:

  1. Crear el índice al momento de crear la tabla.
    CREATE TABLE nombreTabla( campo1 TIPO, campo2 TIPO,
    FULLTEXT [nombreIndice] (campo1 [campo2,...]) );
  2. Crear el índice una vez que ha sido creada la tabla.
    ALTER TABLE nombreTabla ADD FULTEXT [nombreIndice] (campo1 [,campo2,...]);

    La siguiente sentencia también se puede usar para crear un índice cuando la tabla ya existe.

    CREATE FULLTEXT INDEX nombreIndice ON nombreTabla(campo1 [,campo2,...]);

Unicamente para fines ilustrativos, consideremos la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos varchar(70));

Podríamos crear un índice FULLTEXT en la columna nombre, en la columna apellidos, o bien, un índice que ocupe ambos campos. A continuación se muestran los tres casos.

CREATE FULLTEXT INDEX idx_nombre ON usuarios(nombre);

CREATE FULLTEXT INDEX idx_apellidos ON usuarios(apellidos);

CREATE FULLTEXT INDEX idx_nombre_apellidos ON usuarios(nombre,apellidos);

Nota: Cuando se tienen grandes cantidades de datos, es mucho más rápido cargar los datos en una tabla que no tiene índices de texto completo y después crear los índices necesarios, ya que la carga de datos en una tabla que ya tiene índices de este tipo es un proceso lento.

. Índices únicos

Los índices únicos son básicamente como los índices ordinarios, excepto que los valores duplicados no son permitidos.

Para crear un índice UNIQUE se tienen básicamente dos opciones:

  1. Crear un índice único cuando la tabla es creada con el uso de la opción UNIQUE.
    CREATE TABLE nombreTabla(campo1 tipoDato, campo2 tipoDato,..
      UNIQUE [nombreIndice] (campo1 [,campo2...]));
  2. O bien, si la tabla ya existe, se usa la sentencia ALTER TABLE.
    ALTER TABLE nombreTabla ADD UNIQUE [nombreIndice] (campo1, campo2) ...

    De igual manera, también es posible usar la sentencia CREATE INDEX para crear un índice único en una tabla existente.

    CREATE UNIQUE INDEX nombreIndice ON nombreTabla(campo1 [,campo2...]);

Unicamente para fines ilustrativos, consideremos de nuevo la siguiente definición de tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos varchar(70));

Podríamos crear un índice UNIQUE en la columna nombre, y un índice UNIQUE en la columna apellidos.

ALTER TABLE usuarios ADD UNIQUE idx_nombre (nombre);

CREATE UNIQUE INDEX idx_apellidos ON usuarios(apellidos);

En el primer caso hacemos uso del comando ALTER TABLE, y en el segundo caso creamos el índice con la sentencia CREATE INDEX.

. Índices compuestos

Los índices compuestos son simplemente aquellos que están basados en múltiples columnas. MySQL únicamente usa un índice por tabla cuando está procesando una consulta. Esto significa que si tenemos varias columnas que frecuentemente aparecen juntas en una cláusula WHERE, tenemos la oportunidad de acelerar estas consultas al crear un índice compuesto.

Si una tabla tiene un índice formado por múltiples columnas, cualquier prefijo más a la izquierda puede ser usado por el optimizador de consultas de MySQL para encontrar las filas. Por ejemplo, si tenemos un índice compuesto por tres columnas (col1, col2, col3), tendríamos capacidades de búsqueda en (col1), (col1, col2) y (col1, col2, col3).

MySQL no puede usar un índice parcial si las columnas no forman un prefijo más a la izquierda del índice. Supongamos que tenemos unas sentencias SELECT como estas:

mysql> SELECT * FROM algunaTabla WHERE col1=valor1;
mysql> SELECT * FROM algunaTabla WHERE col2=valor2;
mysql> SELECT * FROM algunaTabla WHERE col2=valor2 AND col3=valor3;

Si el índice existe en (col1, col2, col3), sólo la primera de estas consultas usará el índice. La segunda y la tercera involucran a las columnas en el índice, pero (col2) y (col2, col3) no son los prefijos más a la izquierda de (col1, col2, col3).

Este es otro ejemplo. Consideremos la siguiente definición de una tabla:

CREATE TABLE usuarios(id int, nombre varchar(50), apellidos varchar(70));

Si frecuentemente hacemos consultas en la tabla usuarios basadas en el nombre como en los apellidos, podemos beneficiarnos de un índice compuesto en las columnas nombre y apellidos.

ALTER TABLE usuarios ADD INDEX idx_nombre(nombre, apellidos);

Debido a la forma en que MySQL construye los índices compuestos, éste puede usar el índice idx_nombre para resolver consultas basadas sólo en el nombre, o en el nombre y los apellidos, sin embargo, no usará el índice en una consulta que haga referencia únicamente a la columna apellidos.

Por ejemplo, de las siguientes tres consultas, sólo las dos primeras harían uso de nuestro índice idx_nombre.

SELECT * FROM usuarios WHERE nombre='Eduardo';
SELECT * FROM usuarios WHERE nombre='Eduardo' AND apellidos='Zarate M';
SELECT * FROM usuarios WHERE apellidos='Zarate M';

La idea es que los índices compuestos pueden usarse frecuentemente para acelerar algunas consultas complejas, pero necesitamos entender sus limitaciones y debemos ejecutar algún tipo de prueba en vez de asumir que estos índices siempre nos van a ayudar.

. Índices de parte de campos

En las columnas CHAR y VARCHAR se nos permite crear un índice que no use el campo por completo. Retomemos el ejemplo anterior de la tabla usuarios. A pesar de que el nombre de una persona puede ser de hasta 50 caracteres, es muy común que los nombres de las personas sean diferentes en los primeros 10 caracteres. Al usar un índice de 10 caracteres en lugar de 50, el índice será más pequeño, y permitirá que las consultas INSERT y UPDATE sean más rápidas, a la vez que no se afecta la velocidad de las consultas SELECT.

Para crear un índice como parte de un campo, sólo se tiene que especificar el tamaño entre paréntesis después del nombre de la columna. Por ejemplo, nuestro índice idx_nombre pudo haber sido creado también de la siguiente manera:

ALTER TABLE usuarios ADD INDEX idx_nombre(nombre(10), apellidos(20));

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.