提高参数化查询性能

Maz*_*har 7 performance sql-server sql-server-2008-r2 query-performance

我的任务是提高下面查询执行计划链接中显示的 SQL Server 2008 R2 查询(在存储过程中)的性能。

它目前在大约 7 秒内执行,如果可能,需要在 1-2 秒内完成。慢查询的每次执行总是在 7 秒左右。查询的结果涓涓细流。被查询的表很大,但不是数十亿行。

行数

行数

根据传递的参数,结果可以是几百行(执行亚秒)到 > 300K 行(这很慢)。

我已经包含了优化器正在使用的慢查询执行计划和索引。这是更快执行计划,并且STATISTICS IO, TIME

AsIs StatsIO_Time

有两个查询正在执行。第一个不是问题。这是我需要帮助的第二个。虽然需要,但删除非 SARGable 谓词 ( AND FT.TripDistance < ( CONVERT(NUMERIC(10,0),FT.TripTime) * 83.33 )) 对速度略有不同

移除非 SARG

删除函数 [FN_GetLocalTime_FromUTC_BasedOnTZId] 对速度略有不同,这里是STATISTICS IO TIME删除非 SARG where 子句和函数:这是执行计划

删除非 SARG 和 Func

这是除了添加LOOP JOIN提示之外的未更改查询的输出。这个比较慢。

循环连接

我注意到,在慢速不变的查询计划中,FACT_trip_Statuses表上 Index Seek 的实际行数 (300330)接近最终输出 (299887)。然而,在索引行(4.87米)的实际数量寻求的xFactTrip_AnnexFACT_Trip以及FACT_Trip_Attributes是出路。我该如何解决?添加OPTION RECOMPILE几乎没有区别

我尝试添加跟踪标志 4199DBCC TRACEON (4199, -1);并在有和没有JOIN提示的情况下重试,没有帮助。

HASH 连接提示和 TF 4199

HASH 连接提示和 TF4199

LOOP 连接提示和 TF 4199

LOOP 连接提示和 TF4199

没有加入提示和 TF 4199

没有 JOIN 提示和 TF4199

指数

CREATE NONCLUSTERED INDEX IDX_FACT_Trip_StartDateUTC_VehicleKey_Includes ON dbo.FACT_Trip
(
    StartDateUTC ASC,
    VehicleKey ASC,
    EndDateUTC ASC
)
INCLUDE (   DriverKey,
    DrivingTime,
    TripDistance,
    TripTime)

CREATE NONCLUSTERED INDEX IX_xFactTrip_Annex_StartDateUTC_MonthlyProcessing ON dbo.xFactTrip_Annex
(
    StartDateUTC ASC
)
INCLUDE (   VehicleKey,
            Spd20Count, Spd20Distance,
            Spd30Count, Spd30Distance,
            Spd40Count, Spd40Distance,
            Spd50Count, Spd50Distance,
            Spd60Count, Spd60Distance,
            Spd70Count, Spd70Distance,
            SpdCat1,SpdCat2,SpdCat3,
            TotalIdling,
            PTOTime,
            TripFuel) 

CREATE NONCLUSTERED INDEX IX_FACT_Trip_Attributes_StartDateUTC_VehicleKey_Includes ON dbo.FACT_Trip_Attributes
(
    StartDateUTC ASC,
    VehicleKey ASC,
    EndDateUTC ASC
)
INCLUDE (   Attribute0Distance,
    Attribute1Distance,
    Attribute2Distance,
    Attribute3Distance,
    Attribute4Distance,
    Attribute5Distance,
    Attribute6Distance,
    Attribute7Distance,
    Attribute8Distance,
    Attribute9Distance,
    Attribute10Distance)

CREATE NONCLUSTERED INDEX IDX_FACT_Trip_Statuses_StartDateUTC_VehicleKey_Includes ON dbo.FACT_Trip_Statuses
(
    VehicleKey ASC,
    StartDateUTC ASC,
    EndDateUTC ASC
)
INCLUDE (   HarshAccelerationCount,
    HarshBrakeCount,
    HarshBumpCount,
    HarshCorneringCount,
    ExcessIdleDuration,
    ExcessIdleCount,
    OverspeedCount)

CREATE NONCLUSTERED INDEX IX_StartDateUTC_VehicleKey_IsBP ON dbo.FACT_TripComments
(
    StartDateUTC ASC
)
INCLUDE (   VehicleKey, IsBusinessPrivate) 
Run Code Online (Sandbox Code Playgroud)

Ric*_*ner 0

现在,这个查询仍然有错误,我无法根据您的数据对其进行测试,但这会产生相同的结果并且运行得更快一点吗?

WITH cteBusGrps
  AS(
   SELECT
    LTRIM(RTRIM(CAST(A.Value AS INT))) 'BusGrpId', BG.BusinessGroupKey
   FROM
    dbo.FN_SplitString_AB (@nvBusGrpIds_csv, ',') A
   CROSS APPLY
    Warehouse.dbo.DIM_BusinessGroup BG
   WHERE
    vn = 1 
   AND
    BG.CtrackNodeID = CAST(A.Value AS INT)
  )
  INSERT INTO #xMobiles
  (
     NodeId
   , VehicleKey
   , VehicleId
   , CostCentreName
   , BusGrpId
   , BusGrpKey
   , AssignStart
   , AssignEnd
   , vGrpId
   , vGrpName
  )
  SELECT 
    V.vNodeId
   ,V.VehicleKey
   ,CAST(V.VehicleId AS NVARCHAR(50))
   ,V.CostCentreName
   ,V.BusGrpId
   ,V.BusinessGroupKey
   ,V.CreateDate
   ,COALESCE(V.DeletedTime,V.DeInstalled_DT,'2100-12-31 23:59:59') 
   ,V.vGrpId
   ,CAST(V.vGrpName AS NVARCHAR(100))
  FROM
   dbo.xED_Mobiles_OCC_ViewTable V
  INNER JOIN
   cteBusGrps      B ON B.BusinessGroupKey = V.BusinessGroupKey
  WHERE
   (
    ( CreateDate <= @dtStartDate_LT AND DeletedTime IS NULL ) 
    OR ( CreateDate <= @dtStartDate_LT AND DeletedTime BETWEEN @dtStartDate_LT AND @dtEndDate_LT )
    OR ( CreateDate BETWEEN @dtStartDate_LT AND @dtEndDate_LT ) 
    OR ( @dtStartDate_LT BETWEEN CreateDate AND COALESCE(V.DeletedTime,V.DeInstalled_DT,'2100-12-31 23:59:59')
  ) 

   SELECT
     M.BusGrpKey
    ,M.VehicleKey
    ,M.AssignStart
    ,M.AssignEnd
    ,FT.StartDateUTC
    ,D.LocalStartDateTime
    ,D.LocalEndDateTime
    ,CASE WHEN ISNULL(FT.DriverKey,0) < 1 THEN 0 ELSE ISNULL(FT.DriverKey,0) END 
            'DriverKey'
    ,CASE WHEN ISNULL(FT.DriverKey,0) < 1 THEN 1 ELSE 0 END
            'UnknownTrips'
    ,FTS.HarshAccelerationCount
    ,FTS.HarshBrakeCount
    ,FTS.HarshBumpCount
    ,FTS.HarshCorneringCount
    ,FTS.ExcessIdleDuration
    ,FTS.ExcessIdleCount
    ,FTS.OverspeedCount
    ,A.Spd20Count
    ,A.Spd20Distance
    ,A.Spd30Count
    ,A.Spd30Distance
    ,A.Spd40Count
    ,A.Spd40Distance
    ,A.Spd50Count
    ,A.Spd50Distance
    ,A.Spd60Count
    ,A.Spd60Distance
    ,A.Spd70Count
    ,A.Spd70Distance
    ,FT.TripDistance
    ,CONVERT(NUMERIC(10,0),FT.TripTime) * 83.33 'Ignore'
    ,FT.DrivingTime
    ,A.TotalIdling
    ,A.PTOTime
    ,FT.TripTime
    ,CAST( A.TripFuel AS DECIMAL(10,3))
            'TripFuel'
    ,CASE 
      WHEN CAST( A.TripFuel AS DECIMAL(10,3)) > 0 
       THEN FT.TripDistance
      ELSE 0
     END      'Tot_TF_DistTravelled'
    ,A.SpdCat1
    ,CAST(A.SpdCat2 AS INT)  'SpdCat2'
    ,CAST(A.SpdCat3 AS INT)  'SpdCat3'
    ,CASE   --EX-660
     WHEN FTA.Attribute0Distance > 0  THEN 0 
     WHEN FTA.Attribute1Distance > 0  THEN 1
     WHEN FTA.Attribute2Distance > 0  THEN 2
     WHEN FTA.Attribute3Distance > 0  THEN 3
     WHEN FTA.Attribute4Distance > 0  THEN 4
     WHEN FTA.Attribute5Distance > 0  THEN 5
     WHEN FTA.Attribute6Distance > 0  THEN 6
     WHEN FTA.Attribute7Distance > 0  THEN 7
     WHEN FTA.Attribute8Distance > 0  THEN 8
     WHEN FTA.Attribute9Distance > 0  THEN 9
     WHEN FTA.Attribute10Distance > 0 THEN 10
     ELSE 0
     END        'AttributeTypeId'
    ,ISNULL( TC.IsBusinessPrivate,0 ) 'BPOverride'
   FROM
    #xMobiles        M
   INNER JOIN
    Warehouse.dbo.FACT_Trip    FT ON FT.VehicleKey = M.VehicleKey
               AND FT.StartDateUTC BETWEEN @dtStartDate_LT AND @dtEndDate_LT
               AND FT.TripDistance < CONVERT(NUMERIC(10,0),FT.TripTime) * 83.33
   INNER JOIN
    dbo.xFactTrip_Annex      A ON A.VehicleKey = FT.VehicleKey
               AND A.StartDateUTC = FT.StartDateUTC
   INNER JOIN
    Warehouse.dbo.FACT_Trip_Statuses FTS ON FTS.VehicleKey = FT.VehicleKey
               AND FTS.StartDateUTC= FT.StartDateUTC
   INNER JOIN 
    Warehouse.dbo.FACT_Trip_Attributes FTA ON FTA.VehicleKey = FT.VehicleKey 
               AND FTA.StartDateUTC= FT.StartDateUTC
   LEFT JOIN
    Warehouse.dbo.FACT_TripComments  TC ON TC.VehicleKey = FT.VehicleKey
               AND TC.StartDateUTC = FT.StartDateUTC
   CROSS APPLY
    dbo.FN_GetLocalTime_FromUTC_BasedOnTZId(FT.StartDateUTC, FT.EndDateUTC, 2) D
   WHERE
   (
    ( FT.StartDateUTC BETWEEN M.AssignStart AND M.AssignEnd )
    OR ( M.AssignStart <= FT.StartDateUTC AND M.AssignEnd BETWEEN FT.StartDateUTC AND FT.EndDateUTC )
   ) 
Run Code Online (Sandbox Code Playgroud)