Ich verwende EF, Linq, TSQL. Ich habe zwei Tabellen:Verbinden Sie 2 Tabellen nach dem ungefähren Zeitstempel
Positions:
Id [int]
Location [geography, nullable]
TimestampLocal [datetimeoffset(7)]
VehicleId [int]
Rawdata:
Id [int]
TimestampLocal [datetimeoffset(7)]
Data1 [string]
VehicleId [int]
Ich brauche die Informationen aus den beiden Tabellen durch Zeitstempel für eine bestimmte VehicleID, mit Zeitstempel zu verbinden, die nahe sind, aber nicht identisch. Ich verwende MoreLinq, um diese Daten zu erhalten. Momentan nehme ich die Positionen in einer Liste, dann die Rawdata in einer anderen Liste, iteriere dann über sie, um den Speicherort eines Rawdata-Beispiels zu erhalten, und tue etwas mit diesen Informationen (berechne einen engstenPos.Location.Intersects (Polygon). ..).
var posList = entities.Positions.Where(z => (z.VehicleId == SearchedVehicleId && z.Location != null)
&& z.TimestampLocal.Day == SearchedDay && z.TimestampLocal.Month == SearchedMonth && z.TimestampLocal.Year == SearchedYear).AsEnumerable().OrderBy(k => k.TimestampLocal);
var rawdatalist=entities.Rawdata.Where(k => (k.VehicleId == SearchedVehicleId)
&& k.TimestampLocal.Day == SearchedDay && k.TimestampLocal.Month == SearchedMonth && k.TimestampLocal.Year == SearchedYear).OrderBy(k => k.TimestampLocal).ToList();
foreach (Rawdata r in rawdatalist){
var closestPos = posList.MinBy(t => Math.Abs((t.TimestampLocal- r.TimestampLocal).Ticks));
//do something with the location
ComputeRawdataforLocation(closestPos, r);
}
Die Daten aus der Datenbank (auch mit AsEnumerable(), ToList()) ist schnell. Das Problem ist, dass es ungefähr 10k Positionen und 100k Rawdata-Werte gibt.
Wie kann ich die Dinge beschleunigen? Ein anderer Weg in Linq? Vielleicht eine TSQL-Prozedur, die ich nennen könnte, die den Werten beitreten würde? Ich habe jedoch keine Ahnung, wie man das in TSQL macht.
Thank you! Ich musste nur eine .ToList() am Ende von posList anwenden, damit es funktioniert. Dies reduzierte die Zeit im Durchschnitt um 10%. Ich schaute jedoch in meinen Code und bemerkte, dass ich einige zusätzliche Abfragen hatte, die noch einige Daten auf dem SQL-Server behielten (ich habe kein AsEnumerable für sie angewendet), also mischte ich lokale IIS-Daten (mit AsEnumerable) mit DB-Abfragedaten (prob. gehalten auf dem DB-Server). Dies beließ die CPU bei 5%. Nach dem Ziehen aller Daten auf dem IIS (mit AsEnumberable) ging die CPU auf 40% und die Rechenzeit nahm drastisch ab, noch mehr mit Ihrem Code. – user3546827
Ich habe übersehen, dass 'posList' keine Liste ist. Aber ich würde vorschlagen, dass Sie 'ToList' am Ende der' var posList = entities .... ToList(); 'aufrufen und dann wie in der Antwort verwenden (nicht' ToList' Aufrufe innerhalb der inneren Schleife)). Es sollte wirklich viel mehr als 10% geben - wenn Sie 10K-Positionen haben, wird die binäre Suche ~ 13 Vergleiche verwenden, während das Original ungefähr tun wird. 5-10K Vergleiche, so sollte die neue Methode mal schneller sein. –