sql >> Databáze >  >> RDS >> Sqlserver

Dva radikálně odlišné dotazy na 4 miliony záznamů se provádějí současně - jeden používá hrubou sílu

Důvěřujte optimalizátoru.

Napište dotaz, který nejjednodušeji vyjadřuje, čeho se snažíte dosáhnout. Pokud máte problémy s výkonem s tímto dotazem byste se měli podívat, zda nechybí nějaké indexy. Ale stále byste neměli muset explicitně pracovat s těmito indexy.

Nestarejte se o to, jak se vy může implementovat takové vyhledávání.

V velmi Ve výjimečných případech může být nutné dotaz dále vynutit, aby používal konkrétní indexy (pomocí nápověd), ale toto je pravděpodobně <0,1 % dotazů.

Ve vašich zaslaných plánech vaše "optimalizovaná" verze způsobuje skenování proti 2 indexům vaší (předpokládám) tabulky Params (PK_Params_1, IX_Params_1). Bez zobrazení dotazů je obtížné zjistit, proč se to děje, ale pokud srovnáváte s jedním skenováním proti tabulce („Brute force“) a dvěma, je snadné pochopit, proč druhý není efektivnější.

Myslím, že bych to zkusil:

        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]

Tj. zaveďte anti-join, který eliminuje výsledky, které nechcete.



  1. Získávání dat pole mysql po kliknutí na odkaz?

  2. Consecutive PreparedStatement osvědčené postupy

  3. Replikace a spouštěče MySQL

  4. Nelze zmenšit databázi „pouze pro čtení“ | Zmenšit protokol transakcí při používání skupiny dostupnosti AlwaysOn