我有一张表格,其中存储了按地理位置类型存储的位置数据(纬度/经度)。
现在此位置数据代表旅程,因此我想计算旅程中的行进距离,每天的距离和每月的距离。因此,为此,我需要一个属性来计算到旅程中下一个位置的距离。
如果我使用带有窗口函数的表中的“选择”来执行此操作,则性能将非常好,执行计划似乎也不错。 Execution Plan
这是查询-
Select
iVehicleMonitoringId,
iAssetId,
iDriverId,
dtUtcDatetime,
sptGeoLocaitonPoint,
fAngel,
sDirection,
fSpeedKPH,
eEventCode,
fDistanceTravelled = sptGeoLocaitonPoint.STDistance(LEAD(sptGeoLocaitonPoint) OVER(PARTITION BY iAssetId ORDER BY dtUTCDateTime)),
eIgnition,
eDoor,
eSeatbelt,
eIgnition2,
sAddress
From dbo.VehicleMonitoringLog
Where iAssetId = 1
AND dtUTCDateTime BETWEEN N'2017-12-27' AND N'2017-12-27 23:59:59.997'
现在,因为我的代码中需要此Distance Calculated属性。我决定使用fDistanceTravelled
属性创建一个SQL视图。
CREATE VIEW [dbo].[TB5_xPT_VehicleMonitoringLogs]
AS
Select
iVehicleMonitoringId = ISNULL(iVehicleMonitoringId, -1),
iAssetId,
iDriverId,
dtUtcDatetime,
sptGeoLocaitonPoint,
fAngel,
sDirection,
fSpeedKPH,
eEventCode,
fDistanceTravelled = sptGeoLocaitonPoint.STDistance(LEAD(sptGeoLocaitonPoint) OVER(PARTITION BY iAssetId ORDER BY dtUTCDateTime)),
eIgnition,
eDoor,
eSeatbelt,
eIgnition2,
sAddress
From dbo.VehicleMonitoringLog
GO
但是,当我将此视图导入到我的实体框架中时,它会超时。所以我检查了执行计划,它与从表中选择的计划不匹配。 View Execution Plan
这是查询-
Select
*
From TB5_xPT_VehicleMonitoringLogs
Where iAssetId = 1
AND dtUTCDateTime BETWEEN N'2017-12-27' AND N'2017-12-27 23:59:59.997'
要在代码中执行此操作,我需要遍历列表中的所有位置日志。
DbGeography prevPoint = null;
foreach (var historyLog in historyLogs)
{
var distanceFromPrevPoint = 0.0;
if (prevPoint != null)
{
var distance = prevPoint.Distance(historyLog.sptGeoLocaitonPoint);
if (distance != null)
distanceFromPrevPoint = Math.Round(((double)distance * .001), 2);
}
var locationLog = Mapper.Map<LocationLogDTO>(historyLog);
locationLog.DistanceTravelled = distanceFromPrevPoint;
prevPoint = historyLog.sptGeoLocaitonPoint;
historyDto.LocationLogs.Add(locationLog);
}
我不想这样做。我需要一种更好的方法。
编辑
图片说明了fDistanceTravelled
列的计算。