Per una query con parametri Non può fare solo due ricerche
WHERE A=@P1 AND B=@P2 AND C=@P3 AND D=@P5
e
WHERE A=@P1 AND B=@P2 AND C=@P4 AND D=@P5
Perché se @P3 = @P4
ciò restituisse erroneamente righe duplicate. Quindi avrebbe bisogno di un operatore che rimuova i duplicati da questi per primi.
Da un test rapido questo fine sembra dipendere dalla dimensione della tabella, indipendentemente dal fatto che tu lo ottenga o meno. Nel test di seguito 245
/ 246
righe è il punto di interruzione tra i piani (questo era anche il punto di interruzione tra l'indice che si adattava tutto su una pagina e diventava 2 pagine foglia e una pagina radice).
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 Pagine / 245 righe
Questo piano ha una ricerca A=1 AND B=2
con un predicato residuo su(C=@C1 OR C=@C2) AND D=5
2 pagine a foglia / 246 righe
Nel secondo piano gli operatori extra sono responsabili della rimozione di eventuali duplicati dal @C1,@C2
primo prima di eseguire le ricerche.
La ricerca nel secondo piano è in realtà una ricerca della distanza tra A=1 AND B=2 AND C > Expr1010
e A=1 AND B=2 AND C < Expr1011
con un predicato residuo su D=5
. Non è ancora una ricerca di uguaglianza su tutte e 4 le colonne. Ulteriori informazioni sugli operatori di piani aggiuntivi sono disponibili qui .
L'aggiunta OPTION (RECOMPILE)
consente di ispezionare i valori dei parametri per i duplicati in fase di compilazione e produce un piano con due ricerche di uguaglianza.
Potresti farlo anche 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
Ma in realtà in questo caso di test sarebbe probabilmente controproducente poiché avere due ricerche nell'indice a pagina singola anziché una aumenta l'IO logico.
OPTION (RECOMPILE)
?