计算列的视图性能问题

时间:2018-08-24 21:23:35

标签: c# sql entity-framework sql-server-2016

我有一张表格,其中存储了按地理位置类型存储的位置数据(纬度/经度)。

现在此位置数据代表旅程,因此我想计算旅程中的行进距离,每天的距离和每月的距离。因此,为此,我需要一个属性来计算到旅程中下一个位置的距离。

如果我使用带有窗口函数的表中的“选择”来执行此操作,则性能将非常好,执行计划似乎也不错。 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列的计算。

enter image description here

0 个答案:

没有答案