2013-05-06 15 views
7

Ich verwende Entity Framework 5, ObjectContext und POCOs auf meiner Datenzugriffsebene. Ich habe eine generische Repository-Implementierung und ich habe eine Methode, die die Datenbank mit Paging mit Skip() und Take() abfragt. Alles funktioniert gut, außer dass die Abfrage-Leistung ist sehr langsam, wenn viele Zeilen das Überspringen (Ich spreche über 170k Zeilen)Entity Framework Skip-Methode läuft sehr langsam

Dies ist ein Auszug aus meiner Anfrage auf Linq to Entities:

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); 

In der übersetzten Abfrage in Transact-SQL bemerkte ich, dass stattdessen die ROW_NUMBER der Verwendung von() Klausel mit der Ansicht seiner eine Unterabfrage und zum Anlegen des ROW_NUMBER machen() direkt zu den Ergebnissen der Unterabfrage ...

Beispiel:

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 

Dies dauert etwa 165 Sekunden. Gibt es eine Idee, wie Sie die Leistung der übersetzten Abfrage verbessern können?

+2

Da die Abfrage ohne Überspringen schnell ist, deutet dies darauf hin, dass das Problem in SQL liegt und nicht in den anderen Bereichen der Leistungsüberlegung im Entity Framework. Daher ist das erste, was ich tun würde, mit SQL Profiler zu diagnostizieren, warum die Abfrage langsam ist. Hast du das versucht? Was hast du gefunden? –

+0

Das habe ich schon gemacht. Ich denke, dass das Problem in der unnötigen Unterabfrage liegt, die von Entity Framework erstellt wird, wenn ich dieselbe Abfrage unter Verwendung von LinqToSql anstelle von Entity Framework mache, ist das Ergebnis nicht dasselbe und die Abfrage ist viel schneller (~ 30 Sekunden). Wenn Sie im obigen Beispiel die SQL-Anweisung sehen, gibt es eine unnötige Unterabfrage für die Tabelle, und die Zeilennummer wird nicht auf die Tabelle, sondern auf die Ergebnisse dieser Unterabfrage angewendet. – Boanerge

+0

Das beantwortet meine Frage nicht wirklich. Die Unterabfrage, die Sie beschuldigen, wird in vielen EF-Abfragen angezeigt, für die keine 165er benötigt werden. SQL Profiler sollte Ihnen genauere Informationen geben. Was genau verursacht die 165s? –

Antwort

0

Ein Grund für die Langsamkeit ist wahrscheinlich, dass Ihr SQL Ihre Zeilen zweimal sortiert.

Um die Abfrage zu steuern, ist die einzige Option, die ich kenne, idPred.SqlQuery ("Select ...", params) aufzurufen. Dadurch können Sie Ihre eigene optimierte Abfrage für die Datenanforderung schreiben.

+2

Wenn Sie mich abstimmen, können Sie bitte kommentieren, um mich wissen zu lassen, was mit meiner Antwort nicht stimmt? –

1

Für diejenigen, die nicht die Kommentare über folgende, vermutete ich das Problem nicht die zusätzliche SELECT, war da, dass zusätzliche SELECT viele EF Anfragen vorhanden ist auf vielen, die 165S nicht in Anspruch nehmen. Ich bemerkte schließlich, dass sein ObjectSet auf eine VIEW referenzierte und fragte sich, ob das ein Teil des Problems sein könnte. Nach einigen Experimenten verengte er das Problem innerhalb der Ansicht auf LEFT JOIN. Ich schlug vor, dass er den Database Tuning Advisor für diese Abfrage ausführen sollte. er tat, und die beiden Indizes vorgeschlagen, das Problem zu beheben.