Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Duas consultas radicalmente diferentes contra 4 mil registros são executadas ao mesmo tempo - uma usa força bruta


Confie no otimizador.

Escreva a consulta que expressa mais simplesmente o que você está tentando alcançar. Se você está tendo problemas de desempenho com essa consulta, você deve verificar se há índices ausentes. Mas você ainda não deveria ter que explicitamente trabalhar com esses índices.

Não se preocupe com considerações de como você pode implementar tal pesquisa.

Em muito Em raras circunstâncias, pode ser necessário forçar ainda mais a consulta a usar índices específicos (por meio de dicas), mas isso provavelmente é <0,1% das consultas.

Em seus planos postados, sua versão "otimizada" está causando varreduras em 2 índices de sua (presumo) tabela de parâmetros (PK_Params_1, IX_Params_1). Sem ver as consultas, é difícil saber por que isso está acontecendo, mas se você estiver comparando com uma única varredura em uma tabela ("força bruta") e duas, é fácil ver por que a segunda não é mais eficiente.

Acho que tentaria:
        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]

Ou seja introduzir um anti-join que elimina os resultados que você não deseja.