Entity Framework Arithabort, ale stále dotazu je pomalý

0

Otázka

Som jednoduchý dotaz

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

Stôl má len 3 Stĺpce a 10 riadkov údajov.

Keď som sa snažil spustiť dotaz z Čistého 5 projekt je prijímanie približne 2.3 sekundy prvýkrát a 500ms (+- 100) pre následné žiadosti. Keď som narazila na istú žiadosť v SSMS to sa vracia v takmer žiadny čas (45ms ako je vidieť v sql profiler).

Implementovali sme ARITHABORT O v z EF tu

Keď vidím v SQL Profiler je nastavenie ARITHABORT, ale stále dotaz trvá rovnaký čas na prvé požiadanie a následné žiadosti.

sql profiler screen shot

Ako môžem dosiahnuť rýchlosť rovnaká ako SSMS dotaz rýchlosť. Potrebujem dotaz spustiť naozaj rýchlosť ako môj projekt má požiadavku na vrátenie odpoveď za 1 sekundu (je Potrebné, aby aspoň 5 jednoduchých DB hovory...ak 1 hovor trvá 500ms potom to je križovatka 1 druhá požiadavka)

Upraviť

Snažil s aj ADO.Net. Výkon čas vzal ako je vidieť v SQL Profiler je 40ms, kde, ako, kedy dosiahol kód je takmer 400ms. Takže veľký rozdiel

        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

Najlepšiu odpoveď

0

Svoje "prvé spustenie" scenár je v zásade-off statické inicializácia DbContext. To je miesto, kde DbContext pracuje sa jej priradenia prvý krát a nastane, keď prvý dotaz je popravený. Typický prístup, aby sa zabránilo tohto javu pre používateľa je mať jednoduché "warm up" dotaz, ktorý beží, keď sa služba spúšťa.. napríklad po poskytovateľa inicializuje, jednoducho povedané niečo ako nasledujúce:

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

Tento slúži aj ako rýchly štart-up skontrolujte, že databáza je dosiahnuteľný a reagovať. Dotaz sám bude robiť veľmi rýchlu prevádzku, ale DbContext vyrieši jeho mapovania v tejto dobe tak všetky novo vytvorené DbContext prípadoch bude reagovať bez toho, aby spôsobili, že náklady pri žiadosti.

Ako pre surové výkonnosti, ak to nie je dotaz, ktorý očakáva sa, že chvíľu trvať a zviazať žiadosť, nechcem , aby to async. Asynchrónne žiadosti sú nie rýchlejšie, sú vlastne trochu pomalšie. Pomocou async žiadosti proti DbContext je o zabezpečenie vašej web server / aplikácia vlákno je citlivý a zároveň potenciálne drahé databázy operácií spracovania. Ak chcete odpoveď, ako rýchlo, ako je to možné, použite synchrónne volania.

Ďalej sa zabezpečilo, že všetky polia ste filtrovanie proti, v tomto prípade Mene, sú indexované. S poľa s názvom Mena vo vašom subjektu ako Reťazec skôr ako CurrencyId FK (int) ukazovacie Meny záznam je už extra indexovanie náklady ako indexy na celé čísla sú menšie/rýchlejšie ako tie na struny.

Môžete tiež nebudete musieť trápiť s AsNoTracking pri používaní Count dotaz. AsNoTracking platí výhradne pri vrátení subjektov (ToList/ToArray/Single/Firstatď.) vyvarovať sa DbContext drží na odkaz na vrátený subjektu. Pri používaní Count/Any alebo projekcia vrátiť vlastnosti od subjektov, pomocou Select tam je žiadny subjekt vrátil na trať.

Tiež zvážiť siete latencie medzi kde kódu aplikácie beží a databázový server. Sú rovnaké stroj alebo je tam pripojenie na sieť v hrať? Ako sa to porovnať, keď plníte SSMS dotaz? Pomocou profiler vás môže vidieť, čo SQL EF je vlastne odoslanie do databázy. Všetko ostatné z hľadiska času je v cene: Získanie žiadosť DB, Dostať sa výsledné údaje späť do žiadateľa, rozobrať, že odpoveď. (Ak v prípade, že ste sa vracajú subjektov, prideľovanie, osídľujúcich, kontrola proti existujúce odkazy, atď... V prípade počíta atď. kontrola existujúcich referencií)

Napokon, presvedčte sa, že ste sa dostať na vrchol výkon, uistite sa, že vaše DbContexts života sú stále krátke. Ak DbContext je otvorené a má mnoho sledovanie dopytov sa spúšťajú v (Výber subjektov bez AsNoTracking) tieto sledované subjekt odkazy hromadí a môže mať negatívny výkon vplyv na budúce otázky, aj keď používate AsNoTracking ako EF vyzerá skontrolovať prostredníctvom sledovať odkazy na subjekty, ktoré môžu vzťahovať/súvisiace s vaše nové príkazy. Mnoho krát som vidieť vývojári predpokladať, DbContexts sú "drahé" takže sa rozhodnúť instantiate ich tak málo, ako je to možné, vyhnúť sa tie náklady, len skončiť vykonaním operácie drahšie v priebehu času.

So všetkým, čo považuje, EF nikdy nebude tak rýchlo, ako surové SQL. To je ORM navrhnuté tak, aby poskytovali pohodlie .Net applications, keď príde na prácu s údajmi. Ktoré pohodlie pri práci s subjekt tried skôr ako sanitácie a písať svoj vlastný raw SQL zakaždým, keď príde s cenou.

2021-11-23 21:59:24

pokiaľ váš komentár týkajúce sa Siete latencie oboch SSMS & Čistý Kód je môj stroj..db je v serveri...a na iné veci, mám len jeden dotaz (to je POC). Tak s rovnakým siete latencie SSMS je schopný preberať v 40ms, kde sa ako Čistý Kód je pri 500ms.....dokonca sa snažil s ADO.NET ako je vidieť na otázku, obaja sú pri 500ms
CrazyMonk

V iných jazykoch

Táto stránka je v iných jazykoch

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