Para una consulta parametrizada No puede hacer dos búsquedas en
WHERE A=@P1 AND B=@P2 AND C=@P3 AND D=@P5
y
WHERE A=@P1 AND B=@P2 AND C=@P4 AND D=@P5
Porque si @P3 = @P4
eso traería incorrectamente filas duplicadas. Por lo tanto, primero necesitaría un operador que eliminara los duplicados.
A partir de una prueba rápida, este final parece depender del tamaño de la tabla, ya sea que lo obtenga o no. En la prueba a continuación 245
/ 246
filas se encuentra el punto de corte entre los planos (este también fue el punto de corte entre el ajuste del índice en una página y se convirtió en 2 páginas de hoja y una página raíz).
CREATE TABLE T(A INT,B INT,C INT,D INT)
INSERT INTO T
SELECT TOP (245) 1,2,3,5
FROM master..spt_values v1
CREATE CLUSTERED INDEX IX ON T(A, B, C, D)
SELECT index_level,page_count, record_count
FROM sys.dm_db_index_physical_stats(db_id(),object_id('T'),1,NULL, 'DETAILED')
DECLARE @C1 INT = 3,
@C2 INT = 4
SELECT * FROM T WHERE A=1 AND B=2 AND (C=@C1 OR C=@C2) AND D=5
DROP TABLE T
1 páginas / 245 filas
Este plan tiene una búsqueda A=1 AND B=2
con un predicado residual en(C=@C1 OR C=@C2) AND D=5
2 páginas de hoja / 246 filas
En el segundo plan, los operadores adicionales son responsables de eliminar los duplicados del @C1,@C2
primero antes de realizar las búsquedas.
La búsqueda en el segundo plan es en realidad una búsqueda de rango entre A=1 AND B=2 AND C > Expr1010
y A=1 AND B=2 AND C < Expr1011
con un predicado residual activado D=5
. Todavía no es una búsqueda de igualdad en las 4 columnas. Puede encontrar más información sobre los operadores de planes adicionales aquí .
Agregar OPTION (RECOMPILE)
le permite inspeccionar los valores de los parámetros para duplicados en tiempo de compilación y produce un plan con dos búsquedas de igualdad.
También podrías lograr eso con
;WITH CTE
AS (SELECT DISTINCT ( C )
FROM (VALUES (@C1),
(@C2)) V(C))
SELECT CA.*
FROM CTE
CROSS APPLY (SELECT *
FROM T
WHERE A=1 AND B=2 AND D=5 AND C = CTE.C) CA
Pero en realidad, en este caso de prueba, probablemente sería contraproducente, ya que tener dos búsquedas en el índice de una sola página en lugar de una aumenta el IO lógico.
OPTION (RECOMPILE)
?