Fidati dell'ottimizzatore.
Scrivi la query che esprime più semplicemente ciò che stai cercando di ottenere. Se stai riscontrando problemi con le prestazioni con quella query, dovresti controllare se ci sono indici mancanti. Ma non dovresti comunque farlo esplicitamente lavorare con questi indici.
Non preoccuparti delle considerazioni su come tu potrebbe implementare una tale ricerca.
In molto in rare circostanze, potrebbe essere necessario forzare ulteriormente la query per utilizzare indici particolari (tramite suggerimenti), ma questo è probabilmente <0,1% delle query.
Nei tuoi piani pubblicati, la tua versione "ottimizzata" sta causando scansioni contro 2 indici della tua tabella (presumo) Params (PK_Params_1, IX_Params_1). Senza vedere le query, è difficile sapere perché ciò sta accadendo, ma se stai confrontando con una singola scansione su una tabella ("forza bruta") e due, è facile capire perché la seconda non è più efficiente.
Penso che ci proverei:
SELECT p.ProductID, ptr.[Rank]
FROM dbo.SearchItemsGet(@SearchID, NULL) AS si
JOIN dbo.ProductDefs AS pd
ON pd.ParamTypeID = si.ParamTypeID
JOIN dbo.Params AS p
ON p.ProductDefID = pd.ProductDefID
JOIN dbo.ProductTypesResultsGet(@SearchID) AS ptr
ON ptr.ProductTypeID = pd.ProductTypeID
LEFT JOIN Params p_anti
on p_anti.ProductDefId = pd.ProductDefID and
(p_anti.ParamLo < si.LowMin or p_anti.ParamHi > si.HiMax)
WHERE si.Mode IN (1, 2)
AND p_anti.ProductID is null
GROUP BY p.ProductID, ptr.[Rank]
Cioè. introduci un anti-join che elimini i risultati che non desideri.