2013-05-06 15 views
5

Mam stronę logowania, która wykonuje bardzo proste zapytanie EF, aby określić, czy użytkownik jest ważny. Przy pierwszym uruchomieniu wykonanie tej kwerendy trwa około 6 sekund. W kolejnych seriach zajmuje to znacznie mniej niż sekundę.Jak zainicjować zapytania modułu Entity Framework, aby je przyspieszyć?

Zajrzałem do artykułu, który mówił o użyciu Application Auto-Start i moje pytanie brzmi: czy istnieje sposób, aby wywołać to zapytanie, aby spowodować, że cache musi się zdarzyć bez wywoływania zapytania lub czy jest to konieczne dla mnie wystarczy wywołać zapytanie z fałszywym zbiorem argumentów?

EDYCJA: Kiedy mówię sześć sekund, mam na myśli czas potrzebny na uzyskanie zapytania. Kod wygląda mniej więcej tak (Uwaga: w tym przypadku ContactID jest int pustych i ustawione na null):

return from contact in _context.Contacts 
      where contact.District == Environment.District && 
      contact.ContactId == (contactID ?? contact.ContactId) 
      select contact; 

To SqlServer 2008, a ja uruchomić profilera do sprawdzenia SQL i czas zwraca się 41 ms dla zapytania, które ostatecznie zostanie wykonane. 6 lub 7 sekundowe opóźnienie ma miejsce, zanim zapytanie osiągnie nawet wartość SQL. Próbuję teraz rzucić okiem na to, by zobaczyć, czy może podać mi więcej szczegółów na temat innych rzeczy, które mogą się dziać w tym samym czasie.

+0

Myślę, że warto byłoby przeprowadzić profilowanie i spróbować dowiedzieć się, gdzie faktycznie występuje opóźnienie. –

+0

narzut EF jest dość lekki i prawdopodobnie nie jest to problemem. Może zainstaluj coś takiego jak Glimpse (pakiet NuGet) i zobacz, co naprawdę jest winne.Możliwe, że zdarzają się inne zdarzenia, które są naprawdę wadliwe (dodatki bootstrap?). –

+0

@RobertHarvey Czy masz na myśli profilowanie SQL lub profilowanie .NET? – Mykroft

Odpowiedz

2

To naprawdę brzmi jak tak zwane "zimne zapytanie". Najważniejszym rozwiązaniem dla zimnych zapytań jest "View Generation", który jest wykonywany raz na AppDomain twojej aplikacji. Zazwyczaj efektem jest to, że pierwsze zapytanie - i nie ma znaczenia, które z nich - jest wolne, a kolejne zapytania są szybkie.

To niekoniecznie musi być zapytanie, które może być wolne. Jeśli pierwszą operacją wykonywaną przez EF w aplikacji jest Insert, który byłby powolny. Lub nawet Attach, który nie dotyka w ogóle bazy danych, również byłby powolny. (Przy okazji jest to dobry prosty przypadek testowy: Dodaj context.Users.Attach(new User()) do uruchomienia aplikacji i zobacz w debugerze, ile czasu potrzeba, aby przejść tę linię.)

We wszystkich przypadkach czas jest zużywany przez budowę wewnętrznej struktury danych w pamięć - lokalne zapytanie "widoki" (nie mają one nic wspólnego z widokami tabel bazy danych) - odbywa się raz dla każdego AppDomain.

View Generation jest opisany bardziej szczegółowo pod numerem here oraz here, gdzie można również znaleźć zasoby, jak "wstępnie wygenerować" te widoki w ramach procesu kompilacji i przed wdrożeniem. (Uwaga: Należy zaktualizować te wstępnie wygenerowane za każdym razem, gdy zmieniasz swój model i ponownie wdrażasz aplikację.)

Alternatywnym sposobem jest rozpoczęcie ładowania aplikacji internetowej uruchamianej okresowo (np. W wyniku jakiegoś procesu, który uderza w witrynę) . W aplikacji rozpocząć byś uruchomić każde zapytanie obojętne lub Attach rzeczy powyżej lub zadzwoń do inicjalizacji EF ręcznie:

using (var context = new MyContext()) 
{ 
    context.Database.Initialize(false); 
} 

Edit

zapomniałem ostatnie rozwiązanie. Po prostu zignoruj ​​6 lub 7 sekund. Jeśli twoja strona zyska sławę i ma odpowiedni ruch, takie zimne zapytanie raczej nie wystąpi, ponieważ proces roboczy IIS rzadko wyłącza AppDomain. Okazjonalny użytkownik, który trafi na stronę w nocy, kiedy takie zamknięcie nastąpiło tuż przedtem, prawdopodobnie jest zbyt zmęczony, aby zauważyć opóźnienie.

+1

To jest kodowanie dla przedsiębiorstw, więc "zdobywanie sławy" nie działa jako rozwiązanie :). Ale myślę, że wywołanie Initialize w połączeniu z automatycznym uruchomieniem aplikacji może rozwiązać mój problem. Sprawdzę to dzisiaj. Dzięki. – Mykroft

+0

"zbyt zmęczony, aby zauważyć opóźnienie." - chyba że są w innej strefie czasowej. – mayu