7 Stimmen

Kendo MVC ToDataSourceResult extrem langsam mit großem IQueryable

Ich habe die Kendo DataSourceResult ToDataSourceResult(this IQueryable enumerable, DataSourceRequest request); Erweiterung umfangreich genutzt und nie ein Leistungsproblem bemerkt, bis jetzt, als ich eine Tabelle mit 40 Millionen Datensätzen abfrage. Die take 10-Abfrage, die ich als Benchmark geschrieben habe, ist identisch mit der übergebenen Anfrage.

Das ist meine Leseaktion:

public ActionResult ReadAll([DataSourceRequest] DataSourceRequest 
{
    var startTimer = DateTime.Now;
    var context = Helpers.EFTools.GetCADataContext();
    Debug.WriteLine(string.Format("{0} : Got Context", DateTime.Now - startTimer));

    var events = from e in context.Events
                 select
                     new Models.Event()
                         {
                             Id = e.Id,
                             DateTime = e.EventDateTime,
                             HostId = e.Door.HostId,
                             SiteId = e.Door.Host.SiteId,
                             UserId = (int)e.UserId,
                             UserName = e.User.FirstName + " " + e.User.Surname,
                             DoorId = e.DoorId,
                             Door = e.Door.Name,
                             Description = e.Description,
                             SubDescription = e.SubDescription
                         };
    Debug.WriteLine(string.Format("{0} : Built Query", DateTime.Now - startTimer));

    var tenRecods = events.OrderByDescending(i => i.DateTime).Take(10).ToList();
    Debug.WriteLine(string.Format("{0} : Taken 10", DateTime.Now - startTimer));

    var result = events.ToDataSourceResult(request);
    Debug.WriteLine(string.Format("{0} : Datasource Result", DateTime.Now - startTimer));

    return this.Json(result);
}

Die Ausgabe von Debug:

00:00:00.1316569 : Got Context
00:00:00.1332584 : Built Query
00:00:00.2407656 : Taken 10
00:00:21.5013946 : Datasource Result

Manchmal läuft die Abfrage jedoch ab. Mit dbMonitor habe ich beide Abfragen erfasst, zuerst die manuelle take 10:

"Project1".id,
"Project1"."C1",
"Project1".hostid,
"Project1".siteid,
"Project1".userid,
"Project1"."C2",
"Project1".doorid,
"Project1"."name",
"Project1".description,
"Project1".subdescription
FROM ( SELECT 
    "Extent1".id,
    "Extent1".userid,
    "Extent1".description,
    "Extent1".subdescription,
    "Extent1".doorid,
    "Extent2"."name",
    "Extent2".hostid,
    "Extent3".siteid,
     CAST("Extent1".eventdatetime AS timestamp) AS "C1",
    "Extent4".firstname || ' ' || "Extent4".surname AS "C2"
    FROM    public.events AS "Extent1"
    INNER JOIN public.doors AS "Extent2" ON "Extent1".doorid = "Extent2".id
    INNER JOIN public.hosts AS "Extent3" ON "Extent2".hostid = "Extent3".id
    INNER JOIN public.users AS "Extent4" ON "Extent1".userid = "Extent4".id
)  AS "Project1"
ORDER BY "Project1"."C1" DESC
LIMIT 10

Und die ToDataSourceRequest-Abfrage:

SELECT 
"GroupBy1"."A1" AS "C1"
FROM ( SELECT Count(1) AS "A1"
    FROM  public.events AS "Extent1"
    INNER JOIN public.doors AS "Extent2" ON "Extent1".doorid = "Extent2".id
)  AS "GroupBy1"

Das ist der DataSourceRequest request Parameter, der übergeben wurde:

request.Aggregates Count = 0
request.Filters Count = 0
request.Groups Count = 0
request.Page 1
request.PageSize 10
request.Sorts Count = 1

Dies ist das Ergebnis von var result = events.ToDataSourceResult(request);

result.AggregateResults null
result.Data Count = 10
result.Errors null
result.Total 43642809

Wie kann ich ein DataSourceResult aus dem events IQueryable mit dem DataSourceRequest auf effizientere und schnellere Weise erhalten?

4voto

Tim Blackwell Punkte 689

Nach Implementierung eines benutzerdefinierten Bindings (vorgeschlagen von Atanas Korchev) mit vielen Debug-Ausgabezeitstempeln war offensichtlich, was das Leistungsproblem verursachte, die Gesamtanzahl.

Beim Betrachten des SQL, das ich aufgenommen habe, wird dies unterstützt, ich weiß nicht, warum ich es nicht früher gesehen habe.

Die Gesamtanzahl der Zeilen schnell zu erhalten, ist eine andere Frage, aber ich werde hier alle Antworten posten, die ich finde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X