Índices en bases de datos: qué son y cómo mejoran las consultas SQL

Un índice de base de datos es una estructura auxiliar que permite localizar filas sin recorrer toda la tabla. Funciona como el índice de un libro: mantiene valores ordenados junto con referencias a los registros, de modo que el motor llega más rápido a la información.
Los índices pueden transformar una consulta lenta, pero no son gratuitos. Ocupan espacio y deben actualizarse cada vez que insertas, modificas o borras datos. La optimización consiste en crear los que respaldan consultas reales y eliminar los que solo añaden costo.
Cómo funciona un índice
Sin índice, el motor puede ejecutar un table scan: leer fila por fila y comprobar la condición. Con un índice adecuado, realiza un index seek o búsqueda equivalente y visita una fracción del conjunto.
La estructura más común es el árbol B o B+. Mantiene las claves ordenadas y permite búsquedas por igualdad, rangos y prefijos:
SELECT *
FROM pedidos
WHERE cliente_id = 8742;
Con un índice sobre cliente_id, el motor navega por el árbol hasta las entradas coincidentes y luego recupera las filas.
Crear un índice en SQL
CREATE INDEX idx_pedidos_cliente
ON pedidos (cliente_id);
Para fechas:
CREATE INDEX idx_pedidos_fecha
ON pedidos (fecha);
El nombre debería indicar tabla y columnas. La sintaxis avanzada varía entre PostgreSQL, MySQL, SQL Server y otros motores.
Índice simple vs compuesto
Un índice simple incluye una columna. Uno compuesto utiliza varias:
CREATE INDEX idx_pedidos_cliente_fecha
ON pedidos (cliente_id, fecha);
Puede ayudar a:
WHERE cliente_id = 8742
AND fecha >= '2026-01-01'
Y normalmente también a una consulta que filtra solo por cliente_id, porque es la primera columna. No suele ayudar igual a una consulta que filtra únicamente por fecha. Es la regla del prefijo izquierdo.
El orden importa: coloca primero las columnas que coinciden con los patrones más importantes de igualdad, rango, ordenación y selectividad, verificándolo con el plan.
Selectividad
La selectividad describe cuántos valores distintos tiene una columna. Un identificador suele ser muy selectivo; una columna booleana, poco.
Un índice aislado en activo, donde el 95 % vale verdadero, puede no compensar: leer casi toda la tabla mediante el índice sería más caro que un escaneo. Un índice compuesto o parcial puede ser mejor.
PostgreSQL permite índices parciales:
CREATE INDEX idx_pedidos_pendientes
ON pedidos (fecha)
WHERE estado = 'pendiente';
Son útiles cuando las consultas se concentran en un subconjunto pequeño.
Índices únicos
CREATE UNIQUE INDEX ux_clientes_email
ON clientes (email);
Además de acelerar, impide duplicados. Si la unicidad es una regla de negocio, exprésala con UNIQUE o un índice único, no solo con una validación en la aplicación.
Las claves primarias suelen crear un índice único automáticamente. Las claves foráneas no siempre quedan indexadas y pueden necesitar uno.
Índices de cobertura
Una consulta puede resolverse solo con el índice si este contiene todas las columnas necesarias:
SELECT fecha, total
FROM pedidos
WHERE cliente_id = 8742
ORDER BY fecha DESC;
Un índice sobre (cliente_id, fecha) que incluya total puede evitar volver a la tabla. La sintaxis INCLUDE existe en algunos motores:
CREATE INDEX idx_pedidos_cliente_fecha
ON pedidos (cliente_id, fecha DESC)
INCLUDE (total);
No incluyas muchas columnas sin medir: el índice crece y encarece escrituras.
Cuándo un índice no se utiliza
Aunque exista, el optimizador puede ignorarlo si:
- la consulta devuelve gran parte de la tabla;
- las estadísticas están desactualizadas;
- aplicas una función sobre la columna;
- hay conversión implícita de tipo;
- el patrón empieza con comodín;
- el orden del índice no coincide;
- la tabla es pequeña;
- el costo estimado del escaneo es menor.
Ejemplo problemático:
WHERE YEAR(fecha) = 2026
Patrón más aprovechable:
WHERE fecha >= '2026-01-01'
AND fecha < '2027-01-01'
EXPLAIN y plan de ejecución
Usa EXPLAIN o el plan del motor:
EXPLAIN
SELECT *
FROM pedidos
WHERE cliente_id = 8742;
Revisa:
- tipo de acceso;
- filas estimadas y reales;
- ordenamientos;
- filtros residuales;
- loops costosos;
- uso del índice;
- lecturas y tiempo.
Una consulta rápida con pocos datos puede degradarse al crecer. Prueba con volúmenes y distribuciones realistas.
Costos de tener índices
Cada índice:
- ocupa disco y caché;
- aumenta trabajo en
INSERT,UPDATEyDELETE; - puede fragmentarse;
- necesita estadísticas;
- añade decisiones al optimizador;
- puede duplicar otro índice.
Una tabla de lectura intensiva admite más índices que una de ingestión masiva. En cargas por lotes, a veces conviene ajustar temporalmente la estrategia, según el motor.
Qué columnas suelen beneficiarse
- claves usadas en
JOIN; - filtros frecuentes y selectivos;
- columnas de
ORDER BY; - combinaciones habituales de filtros;
- restricciones únicas;
- claves foráneas consultadas.
No indexes automáticamente:
- todas las columnas;
- campos con poca selectividad sin un patrón específico;
- columnas que cambian constantemente;
- expresiones que nunca aparecen en consultas.
Errores frecuentes
- Crear un índice por cada consulta sin revisar solapamientos.
- Elegir mal el orden de un índice compuesto.
- Usar
SELECT *y perder cobertura. - Medir solo tiempo, sin lecturas ni plan.
- Ignorar el costo de escritura.
- Mantener índices duplicados.
- Pensar que un índice corrige un diseño de base de datos deficiente.
- Añadir hints antes de corregir estadísticas y consultas.
Preguntas frecuentes
¿Qué es un índice en SQL?
Es una estructura auxiliar que organiza claves y referencias para encontrar filas con menos lecturas.
¿Un índice siempre acelera una consulta?
No. Ayuda si coincide con el filtro y devuelve una parte razonable de la tabla; en otros casos el motor puede preferir un escaneo.
¿Cuántos índices debe tener una tabla?
No existe un número ideal. Deben justificar su costo con consultas reales, frecuencia y criticidad.
¿Cuál es la diferencia entre índice y clave primaria?
La clave primaria es una restricción de identidad y unicidad; normalmente se implementa con un índice, pero no todo índice es una clave.
¿Importa el orden en un índice compuesto?
Sí. Determina qué prefijos y patrones de búsqueda puede aprovechar el motor.
¿Por qué un índice hace más lentos los INSERT?
Porque, además de escribir la fila, el motor debe insertar las claves en cada estructura indexada.

Deja una respuesta