2013-05-06 12 views
7

Używam Entity Framework 5, ObjectContext i POCO na mojej warstwie dostępu do danych. Mam ogólną implementację repozytorium i mam metodę, która wysyła zapytanie do bazy danych za pomocą stronicowania przy użyciu funkcji Pomiń() i Take(). Wszystko działa poprawnie, oprócz tego, że wydajność zapytań jest bardzo powolny podczas przeskakiwania dużo wierszy (mówię o 170k wierszy)Metoda Entity Framework działa bardzo wolno

Jest to fragment z mojej kwerendy na Linq do podmiotów:

C# Code :

ObjectContext oc = TheOBJEntitiesFactory.CreateOBJEntitiesContext(connection); 
var idPred = oc.CreateObjectSet<view_Trans>("view_Trans").AsQueryable(); 
idPred = idPred.OrderBy(sortColumn, sortDirection.ToLower().Equals("desc")); 
var result = idPred.Skip(iDisplayStart).Take(iDisplayLength); 
return new PagedResult<view_Trans>(result, totalRecords); 

w tłumaczonych zapytania Transact SQL zauważyliśmy, że zamiast stosowania ROW_NUMBER() zapis z widokiem bezpośrednio jego wytwarzania sub-zapytanie i stosowania ROW_NUMBER() z wynikami sub-zapytania ...

przykład:

select top(10) extent1.A, extent1.B.extent1.C from (
select extent1.A, extent1.B, extent1.C, 
row_number() OVER (ORDER BY [Extent1].[A] DESC) AS [row_number] 
from (
select A,B,C from table as extent1)) as extent1 
WHERE [Extent1].[row_number] > 176610 
ORDER BY [Extent1].[A] DESC 

Trwa to około 165 sekund. Masz pomysł, jak poprawić wydajność przetłumaczonego zapytania zapytania?

+2

Ponieważ zapytanie jest szybkie bez pomijania, sugeruje to, że problem występuje w SQL, a nie w innych obszarach uwzględniania wydajności w Entity Framework. Dlatego pierwszą rzeczą, jaką mógłbym zrobić, to użycie programu SQL Profiler do zdiagnozowania, dlaczego zapytanie jest wolne. Czy próbowałeś tego? Co znalazłeś? –

+0

Już to zrobiłem. Myślę, że problemem jest niepotrzebne podzapytanie, które jest budowane przez Entity Framework, kiedy robię to samo zapytanie przy użyciu LinqToSql zamiast Entity Framework, wynik nie jest taki sam, a zapytanie jest dużo szybsze (~ 30 sekund). Jeśli widzisz Sql w powyższym przykładzie, istnieje niepotrzebne pod-zapytanie do tabeli, a numer_wiersza nie jest stosowany do tabeli, ale do wyników tego pod-zapytania. – Boanerge

+0

To nie odpowiada na moje pytanie. Podzapytanie, które obwiniasz, pojawia się w wielu zapytaniach EF, które nie kończą się 165s. Program SQL Profiler powinien dostarczyć bardziej szczegółowych informacji. Co, dokładnie, wywołuje 165s? –

Odpowiedz

0

Powodem powolności jest prawdopodobnie to, że twój sql zamawia twoje wiersze dwa razy.

Aby kontrolować zapytanie, jedyną dostępną opcją jest wywołanie idPred.SqlQuery ("Select ...", params). Umożliwi to napisanie własnego zoptymalizowanego zapytania dla żądania danych.

+2

Jeśli zamierzasz mnie głosować, czy mógłbyś skomentować, aby dać mi znać, co jest nie tak z moją odpowiedzią? –

1

Dla osób, które nie podążały za powyższymi komentarzami, podejrzewałem, że problem nie jest dodatkowym SELECT, ponieważ ten dodatkowy SELECT jest obecny w wielu, wielu zapytaniach EF, które nie trwają 165 sekund. W końcu zauważyłem, że jego ObjectSet odwołuje się do VIEW i zastanawiałem się, czy to może być część problemu. Po kilku eksperymentach, zawęził problem do poziomu LEFT JOIN w widoku. Zasugerowałem, że uruchomił Doradcę dostrajania bazy danych w tym zapytaniu; zrobił to, a oba wskaźniki sugerowały, że problem został rozwiązany.