Tutorial completo de MySQL 8: instalación, administración, tipos de datos y backup (2026)

Los índices son la herramienta más importante para optimizar el rendimiento de MySQL. Sin el índice correcto, una consulta sobre una tabla con un millón de filas puede tardar segundos; con el índice adecuado, se resuelve en microsegundos. Pero los índices también tienen un coste: ocupan espacio y ralentizan las escrituras, porque cada INSERT, UPDATE y DELETE debe actualizar también los índices.

En este capítulo cubrimos los tipos de índices que soporta MySQL InnoDB, cómo crearlos, cómo verificar con EXPLAIN que se usan, y las pautas para decidir qué columnas indexar.

Tipos de índices en MySQL InnoDB

Tipo

Descripción

PRIMARY KEY

Índice clúster: las filas se almacenan ordenadas por la PK. Solo puede haber uno por tabla.

UNIQUE

Como INDEX pero no permite duplicados. Null sí está permitido (varias filas pueden ser NULL).

INDEX (KEY)

Índice secundario B-tree estándar. Acelera búsquedas, rangos y ordenaciones.

FULLTEXT

Para búsquedas de texto completo con MATCH...AGAINST. Soportado en InnoDB desde MySQL 5.6.

SPATIAL

Para tipos de datos geométricos (POINT, POLYGON, etc.).

Crear índices

-- Al crear la tabla
CREATE TABLE pedidos (
    id         INT UNSIGNED NOT NULL AUTO_INCREMENT,
    id_cliente INT UNSIGNED NOT NULL,
    fecha      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    estado     VARCHAR(20) NOT NULL,
    PRIMARY KEY (id),
    INDEX idx_cliente (id_cliente),
    INDEX idx_estado_fecha (estado, fecha)  -- índice compuesto
);

-- En una tabla existente
CREATE INDEX idx_ciudad ON clientes (ciudad);
CREATE UNIQUE INDEX idx_email ON clientes (email);

-- Con ALTER TABLE
ALTER TABLE pedidos ADD INDEX idx_fecha (fecha);
ALTER TABLE pedidos ADD UNIQUE KEY uk_referencia (referencia_externa);

-- Ver los índices de una tabla
SHOW INDEXES FROM pedidos;

Eliminar índices

DROP INDEX idx_ciudad ON clientes;
ALTER TABLE clientes DROP INDEX idx_ciudad;  -- equivalente

EXPLAIN: verificar el uso de índices

-- Ver el plan de ejecución
EXPLAIN SELECT * FROM pedidos WHERE estado = 'pagado' AND fecha > '2026-01-01'\G

-- Columnas clave del resultado:
-- type:   'const' = PK lookup (óptimo); 'ref' o 'range' = usa índice; 'ALL' = full scan (lento)
-- key:    nombre del índice usado (NULL = ninguno)
-- rows:   estimación de filas a examinar
-- Extra:  'Using index' = cubierto por índice; 'Using filesort' = ordenación sin índice

-- EXPLAIN ANALYZE (MySQL 8.0.18+): ejecuta la consulta y muestra tiempos reales
EXPLAIN ANALYZE SELECT * FROM pedidos WHERE estado = 'pagado'\G

Índices compuestos: el orden importa

-- Índice (estado, fecha) sirve para:
-- WHERE estado = 'pagado'                       ← usa el índice (prefijo)
-- WHERE estado = 'pagado' AND fecha > '2026-01-01'  ← usa el índice completo
-- ORDER BY estado, fecha                        ← usa el índice para ordenar

-- NO sirve para:
-- WHERE fecha > '2026-01-01'   ← no empieza por la primera columna del índice

-- Añadir un índice separado para fecha si también necesitas buscar solo por fecha:
CREATE INDEX idx_fecha ON pedidos (fecha);

Cuándo añadir un índice

Candidatos buenos para un índice:

  • Columnas que aparecen frecuentemente en WHERE, JOIN ON u ORDER BY
  • Claves foráneas (InnoDB no las indexa automáticamente — debes hacerlo manualmente)
  • Columnas con alta cardinalidad (muchos valores distintos: emails, IDs)

Candidatos malos:

  • Columnas con baja cardinalidad (estado con 3 valores posibles puede no valer la pena)
  • Columnas raramente usadas en WHERE
  • Tablas muy pequeñas (el full scan es más rápido que navegar el B-tree)
  • Tablas con escrituras muy frecuentes (cada índice extra ralentiza los INSERTs)

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP