Arrojemos un millón de filas en una tabla temporal junto con algunas columnas:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);
INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM
(
SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values v1,
master..spt_values v2
) t;
CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);
Aquí tengo un índice agrupado (por defecto) en la PKcolumna. Hay un índice no agrupado COL1que tiene una columna clave de COL1e incluye COL2.
Considere la siguiente consulta:
SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;
Aquí no estoy usando BETWEENporque Aaron Bertrand está dando vueltas a esta pregunta.
¿Cómo debe optimizar SQL Server esa consulta? Bueno, sé que el filtro PKactivado reducirá el conjunto de resultados a cinco filas. El servidor SQL puede usar el índice agrupado para saltar a esas cinco filas en lugar de leer todos los millones de filas de la tabla. Sin embargo, el índice agrupado solo tiene la columna PK como una columna clave. Una vez que la fila se lee en la memoria, debemos aplicar el filtro COL2. Aquí, PKes un predicado de búsqueda y COL2es un predicado.

El servidor SQL encuentra cinco filas usando el predicado de búsqueda y reduce aún más esas cinco filas a una fila con el predicado normal.
Si defino el índice agrupado de manera diferente:
CREATE TABLE #174860 (
PK INT NOT NULL,
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);
Y ejecuto la misma consulta obtengo resultados diferentes:

En este caso, SQL Server puede buscar utilizando ambas columnas en la WHEREcláusula. Se lee exactamente una fila de la tabla utilizando las columnas clave.
Para un ejemplo más, considere esta consulta:
SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;
El índice IX_174860_IX es un índice de cobertura porque contiene todas las columnas necesarias para la consulta. Sin embargo, solo COL1es una columna clave. SQL Server puede buscar con esa columna para encontrar las 1000 filas con un COL1valor coincidente . Puede filtrar aún más esas filas en la COL2columna para reducir el conjunto de resultados finales a 0 filas.
