Un índice es una estructura de datos que mejora la velocidad de las operaciones de recuperación de datos en una tabla.
Imagina que tienes un libro de texto de 1.000 páginas y te pido que busques la definición de “Polimorfismo”. Tienes dos opciones:
- Full Scan: Empiezas en la página 1, lees la 2, la 3… hasta que (con suerte) en la página 750 lo encuentras.
- Index Seek: Vas al final del libro, miras el índice alfabético, buscas la “P”, encuentras “Polimorfismo: pág 750” y vas directo allí.
En SQL Server ocurre lo mismo. Si no tienes índices, el motor hace un Full Table Scan (lee toda la tabla). Si tienes índices, va directo al dato. La diferencia de tiempo puede ser de minutos vs milisegundos.
En SQL Server existen dos tipos fundamentales que debes diferenciar: Clustered (Agrupado) y Non-Clustered (No Agrupado).
| Característica | Clustered | Non-Clustered |
|---|---|---|
| Cantidad | Máximo 1 por tabla | Múltiples por tabla |
| Físico | Ordena los datos físicamente | Estructura lógica aparte |
| Contenido | Contiene todos los datos de la fila | Contiene la clave + puntero |
| Velocidad | El más rápido para leer | Rápido, pero puede requerir Lookup |
| Uso ideal | Primary Key, columnas de rango (Fechas), columnas de ordenación frecuente | Claves foráneas, columnas de filtros WHERE habituales |
Vamos a verlos en detalle 👇
Índice Clustered
El índice Clustered es la tabla en si. Es decir, determina el orden físico en el que los datos se almacenan en el disco.
Piensa en una agenda de contactos. Los datos en sí mismos (nombre y apellidos) están ordenados alfabéticamente. No hay una lista aparte; el propio libro es la lista ordenada.
- Solo puede haber UN índice Clustered por tabla. (Lógico, no puedes ordenar físicamente los folios del libro por Apellido y por Fecha de Nacimiento a la vez).
Relación con la Primary Key
Por defecto, cuando creas una PRIMARY KEY, SQL Server crea automáticamente un índice Clustered sobre esa columna. Por eso las búsquedas por ID son tan rápidas.
-- Crear un índice Clustered explícitamente (si no existiera PK)
CREATE CLUSTERED INDEX IX_Clientes_Email
ON Clientes(Email);
Elige bien la Primary Key, suele ser la columna por la que más buscas (ID, Fecha, Código).
Si creas un Clustered Index sobre una columna aleatoria (como Estado), toda la tabla se reordenará físicamente en el disco.
Índice Non-Clustered
El índice Non-Clustered es una estructura separada de la tabla principal. Contiene los valores de la columna indexada y un puntero hacia la fila real.
Siguiendo con los ejemplos, es el índice al final de un libro. Es una lista aparte ordenada alfabéticamente que te dice: “El concepto X está en la página 5”. Tú buscas en el índice y luego tienes que ir a la página (esto se llama Lookup).
- Puedes tener múltiples índices Non-Clustered en una tabla (hasta 999, aunque no te lo recomiendo 😊).
Son ideales para columnas que usas frecuentemente en el WHERE o JOIN pero que no son la clave primaria.
-- Crear un índice para buscar rápido por Apellido
CREATE NONCLUSTERED INDEX IX_Clientes_Apellido
ON Clientes(Apellido);
Ahora, si haces SELECT * FROM Clientes WHERE Apellido = 'García', SQL usará este índice en lugar de leer toda la tabla.
Técnicamente, un índice es una estructura de datos (generalmente un Árbol B o B-Tree) que guarda los valores de una o más columnas de forma ordenada, junto con punteros que nos dicen dónde encontrar el resto de la información.
¿Por qué no indexar todo? El Coste
Si los índices son tan buenos, ¿por qué no ponemos uno en cada columna? Porque los índices no son gratis.
- Espacio: Ocupan espacio en disco y memoria RAM.
- Mantenimiento (Lo más importante): Cada vez que haces un
INSERT,UPDATEoDELETE, SQL Server tiene que actualizar la tabla Y ADEMÁS todos los índices que apunten a esa tabla.
- Una tabla con 20 índices será rapidísima para leer (
SELECT), pero lenta para escribir.
