Diferencia entre Seek Predicate y Predicate

12

Estoy tratando de ajustar el rendimiento de una consulta que tenemos en SQL Server 2014 Enterprise.

He abierto el plan de consulta real en SQL Sentry Plan Explorer y puedo ver en un nodo que tiene un predicado de búsqueda y también un predicado

¿Cuál es la diferencia entre Seek Predicate y Predicate ?

ingrese la descripción de la imagen aquí

Nota: Puedo ver que hay muchos problemas con este nodo (por ejemplo, las filas Estimadas vs Reales, el IO residual), pero la pregunta no se relaciona con nada de eso.

Greg
fuente
3
El predicado de búsqueda ayuda con la unión, filtrando solo a las filas que también se encuentran en la otra tabla (que ha redactado). El predicado (un predicado residual) a continuación, elimina las filas con la situación específica de 2.
Aaron Bertrand
55
Rob Farley declaró lo siguiente en un comentario aquí :The Seek Predicate can be used to find the start of the RangeScan and then when to stop, while the Predicate is the "check" that is applied to every row in the Range.
Aaron Bertrand

Respuestas:

18

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.

ingrese la descripción de la imagen aquí

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:

ingrese la descripción de la imagen aquí

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.

ingrese la descripción de la imagen aquí

Joe Obbish
fuente