En los post anterior (parte 3) vimos como los clustered index controlan el orden físico de las filas en la tabla. Ahora veremos como operan los índices Non-Clustered.
La siguiente ilustración muestra la estructura que tiene un non-clustered index.
Al igual que en el caso de los clustered index, los non-clustered index tienen un nodo raíz y muchos nodos en los niveles intermedios, estos a su vez pueden apuntar a nodos hojas o a otros nodos intermedios. La diferencia se presenta en los nodos hoja, estos tienen almacenados solo el Id del registro y no todo el registro, por lo que se hacer necesario hacer una búsqueda sobre el índice cluster o sobre el heap para obtener el resto de las columnas de la fila.
La búsqueda parte desde el nodo raíz, este nodo tiene una lista de llaves, se comparan estas llaves para encontrar el nodo de nivel intermedio que contenga un rango de llaves que cubra la llave que se está buscando. Luego se repite el proceso en los nodos intermedios hasta que se encuentre la llave que identifica a la fila correspondiente a la llave del índice.
Para ilustrar este proceso, realicemos una búsqueda de la llave AX04 sobre un non-clustered index.
Paso 1.- Contenido del Nodo Raíz (ID 0)
| Llave Índice | ID Nodo Intermedio |
| AA01 | 1 |
| AG01 | 2 |
| BA01 | 3 |
| DB02 | 4 |
| RF04 | 5 |
| KJ01 | 6 |
Paso 2.- Contenido del Nodo Intermedio (ID 2)
| Llave Índice | ID Nodo Intermedio |
| AG01 | 10 |
| AJ10 | 11 |
| AP20 | 12 |
| AZ30 | 13 |
| BA20 | 14 |
| BH50 | 15 |
Paso 3.- Contenido del Nodo Hoja (ID 12)
| Llave Índice | Llave |
| AP20 | 101 |
| AQ10 | 50 |
| AR12 | 160 |
| AX04 | 123 |
| AX24 | 145 |
| AY25 | 12 |
Paso 4.- Hemos encontrado la fila (123), ahora debemos realizar una búsqueda utilizando índice cluster, conocido como bookmark lookup en SQL Server 2000/2005 y como key lookup en SQL Server 2008.
Llave ID Nodo Intermedio 1 1 100 2 160 3 300 4 500 5 1000 6
Paso 5.- Contenido del Nodo Intermedio (ID 2)
Llave ID Nodo Intermedio 100 10 110 11 120 12 130 13 140 14 150 15
Paso 6.- Contenido del Nodo Hoja (ID 12)
| Llave | Columna 1 | Columna 2 | … | Columna N |
| 120 | AX06 | 10000 | XXX | |
| 121 | AX02 | 10004 | XXX | |
| 122 | AX07 | 10000 | XXX | |
| 123 | AX04 | 20000 | XXX | |
| 124 | AX08 | 9000 | XXX | |
| 125 | AX01 | 1 | XXX |
En SQL Server la Llave Índice puede ser una o varias columnas, siempre y cuando el largo combinado de estas columnas no supere los 900 bytes.
Columnas Incluidas
SQL Server 2005 agregó una nueva funcionalidad a los índices non-clustered llamada “Columnas Incluidas” estas columnas no son parte de la llave índice, por lo que no se mantienen ordenadas dentro del índice y como consecuencia de esto solo es necesario almacenar su valor en el nodo hoja del índice.
En el ejemplo anterior, el paso 3 quedaría así al agregar la Columna 2 como una columna incluida del índice:
| Llave Índice | Llave | Columna Incluida (Columna 2) |
| AP20 | 101 | 12000 |
| AQ10 | 50 | 12332 |
| AR12 | 160 | 12344 |
| AX04 | 123 | 20000 |
| 124 | 145 | 12233 |
| 125 | 12 | 12221 |
Las columnas incluidas tienen varias ventajas:
- Al utilizar columnas incluidas en el índice es posible superar la limitación de los 900 bytes para la llave del índice, manteniendo un índice eficiente.
- Las modificaciones al valor de una columna incluida es más eficiente que la modificación de una columna que es parte de la llave del índice pues estas no requieren ser mantenidas en orden.
- Es posible crear Covering Indexes, que son índices que incluyen todas las columnas requeridas para contestar una consulta específica, que no requieren la búsqueda sobre el clustered index. Este tipo de índice es igual o más eficiente que u índice cluster.
Índices Filtrados
SQL Server 2008 agregó otra mejora a los índices non-clustered llamada “Índices Filtrados”. Estos índices mantienen ordenados un sub conjunto de las filas de la tabla.
El uso más común de este tipo de índices se da cuando queremos crear un índice sobre una columna que permite valores nulos. Al crear un índice normal podemos desperdiciar una gran parte del espacio de índice ordenando filas que tienen un valor nulo.
A continuación se describen algunos ejemplos de casos de uso para estos índices filtrados:
- La columna “fecha de término de contrato” de la tabla empleado contiene una gran cantidad de filas con el valor nulo.
- Los estados intermedios son buenos candidatos para ser índices filtrados. Es posible crear un índice que solo contenga las ordenes de compra recibidas y en proceso, pero no las despachadas.
Referencias: