Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Due query radicalmente diverse su record da 4 mil vengono eseguite contemporaneamente:una utilizza la forza bruta

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.