以下のクエリ実行プランのリンクに示されている(ストアドプロシージャ内の)SQL Server 2008 R2クエリのパフォーマンスを向上させる必要があります。
現在、約7秒で実行され、可能であれば1〜2秒で完了する必要があります。遅いクエリの各実行は常に約7秒です。クエリの結果は少しずつ流れていきます。照会されるテーブルは大きいが、数十億行ではない。
渡されるパラメーターに応じて、結果は数百行(1秒未満で実行)から> 300K行(これは遅い)のいずれかになります。
スロークエリ実行プラン とオプティマイザで使用されているインデックスを含めました。これは より迅速な実行のための計画 および_STATISTICS IO, TIME
_です。
2つのクエリが実行されています。最初のものは問題ではありません。それは私が助けを必要とする2番目のものです。 SARGableでない述語(AND FT.TripDistance < ( CONVERT(NUMERIC(10,0),FT.TripTime) * 83.33 )
)を削除することは必要ですが、速度にわずかな違いがあります
関数[FN_GetLocalTime_FromUTC_BasedOnTZId]を削除すると、速度にわずかな違いが生じます。ここに_STATISTICS IO TIME
_があり、SARG以外のwhere句と関数の両方を削除しています。ここに 実行計画 があります
_LOOP JOIN
_ヒントを追加する以外の変更されていないクエリの出力を次に示します。これは遅いです。
遅い変更のないクエリプランでは、_FACT_trip_Statuses
_テーブルのインデックスシークの実際の行数(300330)が最終出力(299887)に近いことに気付きました。ただし、_xFactTrip_Annex
_、_FACT_Trip
_、および_FACT_Trip_Attributes
_でのインデックスシークの実際の行数(4.87m)は異常です。どうすれば修正できますか? _OPTION RECOMPILE
_を追加しても、ほとんど違いはありません
トレースフラグ4199 DBCC TRACEON (4199, -1);
を追加して、JOIN
ヒントを付けて、または付けずに再試行しましたが、役に立ちませんでした。
_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)
_
おそらく、#xMobiles一時テーブルに対するクラスター化インデックスは、最後の結合に役立ちます。
CREATE CLUSTERED INDEX IDX_xMobiles_VehicleKey ON #xMobiles
(
VehicleKey ASC,
)
最適なオプションは、テーブルにデータを入力した後でインデックスを作成することです。
さて、このクエリにはまだ障害があり、データに対してテストすることはできませんが、同じ結果が得られ、少し速く実行されますか?
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 )
)