Entity Framework Arithabort, ale ještě dotaz je pomalý

0

Otázka

Mám jednoduchý dotaz

var count =  await _context.ExchangeRate.AsNoTracking().CountAsync(u => u.Currency == "GBP");

Tabulka má pouze 3 Sloupce a 10 řádků údajů.

Když jsem se pokusil provést dotaz z Čistých 5 projekt trvá kolem 2,3 sekundy poprvé a 500ms (+- 100) pro následné požadavky. Když jsem narazila na stejnou žádost v SSMS se vrací v téměř žádný čas (45ms, jak je vidět v sql profiler).

Jsem implementoval ARITHABORT NA v EF z tu

Když vidím v SQL Profiler je nastavení ARITHABORT ON ale stále dotazu trvá stejnou dobu pro první žádost, a v následujících požadavků.

sql profiler screen shot

Jak mohu dosáhnout rychlosti stejné jako SSMS rychlosti dotazu. Potřebuji dotaz spustit opravdu rychlost jako můj projekt má požadavek na návrat reakce na 1 sekundu (je Třeba, aby alespoň 5 jednoduchých DB hovory...pokud 1 hovor trvá 500ms pak je přechod 1 druhý požadavek)

Edit

Snažil se i ADO.Net. Provádění dobu trvalo, jak je vidět v SQL Profiler je 40ms, kde, jak, kdy dosáhla kód je téměř 400ms. Tak velký rozdíl

        using (var conn = new SqlConnection(connectionString))
        {
            var sql = "select count(ExchangeRate) as cnt from ExchangeRate  where Currency = 'GBP'";

            SqlCommand cmd = new SqlCommand();

            cmd.CommandText = "SET ARITHABORT ON; " + sql;
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;
            conn.Open();
            var t1 = DateTime.Now;
            var rd =  cmd.ExecuteReader();
            var t2 = DateTime.Now;
            TimeSpan diff = t2 - t1;

           Console.WriteLine((int)diff.TotalMilliseconds);
          
          while (rd.Read())
          {
               Console.WriteLine(rd["cnt"].ToString());
          }
            conn.Close();
        }
1

Nejlepší odpověď

0

Váš "první spuštění" scénář je obecně jeden-off statické inicializace DbContext. To je místo, kde DbContext vyjde jeho mapování poprvé a dojde při první dotaz je spuštěn. Typický přístup, aby se zabránilo, že se to stane pro uživatele je jednoduché "warm up" dotaz, který se spustí při spuštění služby.. například poté, co vaše služby inicializuje, jednoduše řečeno něco jako následující:

// Warm up the DbContext
using (var context = new AppDbContext())
{
    var hasUser = context.Users.Any();
}

To také slouží jako rychlý start-up ověřit, že databáze je dosažitelné a reagovat. Dotaz sám bude dělat velmi rychlá operace, ale DbContext bude řešit jeho mapování v této době tak žádné nově vytvořené DbContext případech bude reagovat aniž by to stálo v žádosti.

Jako na surový výkon, pokud to není dotaz, který se očekává, že trvat a svázat žádost, nechci, aby to async. Asynchronní požadavky jsou ne rychleji, oni jsou vlastně trochu pomalejší. Pomocí async požadavky proti DbContext se o zajištění webový server / aplikaci vlákno je citlivé, zatímco potenciálně drahé operace databáze zpracování. Jestli chceš odpověď tak rychle, jak je to možné, použijte synchronní volání.

Dále se ujistěte, že všechna pole jsou filtrování proti, v tomto případě Měny, jsou indexovány. S pole s názvem Měně ve vašem jednotka jako Řetězec, spíše než CurrencyId FK (int) ukazuje na Měnový záznam je již navíc indexování nákladů jako indexy na celá čísla jsou menší/rychlejší než ty, na struny.

Můžete také nemusíte obtěžovat s AsNoTracking při použití Count dotaz. AsNoTracking platí pouze, když jste vykazujících subjektů (ToList/ToArray/Single/Firstatd.) abychom se vyhnuli DbContext drží na odkaz na vrácené entity. Při použití Count/Any nebo projekce vrátit vlastnosti z entit pomocí Select tam je žádný subjekt se vrátil na trať.

Také zvážit, latence sítě mezi, kde se vaše aplikace kód je spuštěn a databázový server. Jsou na stejném počítači, nebo je tam připojení k síti hrát? Jak to porovnat, když provádíte SSMS dotaz? Pomocí profiler můžete vidět, co to SQL, EF je vlastně odesílání do databáze. Vše ostatní z hlediska času je cena: na vyžádání k DB, jak se výsledná data zpět žadateli, parsování, že odpověď. (Pokud se v případě, kdy se vrací subjektů, přidělování, naplnění, kontrola proti stávající odkazy, atd... V případě počítá atd. kontrola stávající odkazy)

A konečně, aby zajistily, že jste získali špičkový výkon, ujistěte se, že vaše DbContexts životy jsou stále krátké. Pokud DbContext je otevřený a má řadu sledování dotazů, spustit proti v (Výběr subjektů bez AsNoTracking) tyto sledované entity odkazy se hromadí a může mít negativní dopad na výkon budoucích dotazů, i když používáte AsNoTracking jako EF vypadá zkontrolovat prostřednictvím je sledován odkazy na subjekty, které by mohly být použitelné/vztahující se k vaší nové dotazy. Mnohokrát jsem vidět, vývojáři předpokládají, DbContexts jsou "drahé", a tak se rozhodnou instanci je tak málo, jak je to možné, aby se zabránilo těchto nákladů, jen aby nakonec dělat operace dražší v průběhu času.

Se vším, co považuje za, EF nebude nikdy tak rychle, jako syrové SQL. To je ORM navržen tak, aby poskytují pohodlí .Net aplikací, pokud jde o práci s daty. To pohodlí při práci s entity tříd, spíše než dezinfekce a psát své vlastní syrové SQL pokaždé, když přijde s náklady.

2021-11-23 21:59:24

pokud jde o vaše komentáře týkající se Sítě, latence obou SSMS a Čistý Kód je v mém počítači..db je v serveru...a za další věci, mám pouze jeden dotaz (POC). Takže se stejnou latencí sítě SSMS je schopen načíst v 40ms, kde, jak Čistý Kód je s 500 ms.....dokonce se snažil s ADO.NET jak je vidět v otázce, jak jsou s 500ms
CrazyMonk

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................