Verbessern Sie die Leistung parametrisierter Abfragen

7

Ich wurde beauftragt, die Leistung einer SQL Server 2008 R2-Abfrage (innerhalb einer gespeicherten Prozedur) zu verbessern, die im folgenden Link zum Ausführungsplan für Abfragen angezeigt wird.

Es wird derzeit in ca. 7 Sekunden ausgeführt und muss nach Möglichkeit in 1-2 Sekunden abgeschlossen werden. Jede Ausführung der langsamen Abfrage dauert immer etwa 7 Sekunden. Die Ergebnisse der Abfrage fließen durch. Die abgefragten Tabellen sind groß, aber nicht Milliarden von Zeilen.

Zeilenanzahl

Zeilenzählungen

Abhängig von den übergebenen Parametern können die Ergebnisse entweder einige hundert Zeilen (die in Sekundenschnelle ausgeführt werden) bis> 300 KB Zeilen (dies ist langsam) sein.

Ich habe den Ausführungsplan für langsame Abfragen und die Indizes aufgenommen, die vom Optimierer verwendet werden. Dies ist der Plan für die schnellere Ausführung und STATISTICS IO, TIME:

AsIs StatsIO_Time

Es werden zwei Abfragen ausgeführt. Der erste ist nicht das Problem. Es ist das zweite, bei dem ich Hilfe brauche. Obwohl dies erforderlich ist, wirkt sich das Entfernen des nicht SARGable-Prädikats ( AND FT.TripDistance < ( CONVERT(NUMERIC(10,0),FT.TripTime) * 83.33 )) geringfügig auf die Geschwindigkeit aus

Nicht-SARG entfernen

Entfernen die Funktion [FN_GetLocalTime_FromUTC_BasedOnTZId] macht geringfügigen Unterschied zu der Geschwindigkeit, ist hier die STATISTICS IO TIMEbeide nicht SARG entfernen where - Klausel und Funktion: Hier sind die Planausführung

Entfernen Sie nicht SARG und Func

Hier ist die Ausgabe für die unveränderte Abfrage, außer dass ein LOOP JOINHinweis hinzugefügt wird . Das ist langsamer.

LoopJoin

Ich habe festgestellt, dass im langsamen, unveränderten Abfrageplan die tatsächliche Anzahl der Zeilen (300330) für die Indexsuche in der FACT_trip_StatusesTabelle nahe an der endgültigen Ausgabe (299887) liegt. Jedoch sucht die tatsächliche Anzahl der Zeilen (4.87m) auf den Index für die xFactTrip_Annex, FACT_Tripund FACT_Trip_Attributesist Ausweg. Wie behebe ich das? Hinzufügen OPTION RECOMPILEmacht wenig Unterschied

Ich habe versucht, das Trace-Flag 4199 DBCC TRACEON (4199, -1);hinzuzufügen und es mit und ohne JOINHinweise erneut zu versuchen , hat nicht geholfen.

HASH Join Hinweis und TF 4199

HASH Join Hinweis und TF4199

LOOP Join Hinweis und TF 4199

LOOP Join Hinweis und TF4199

Keine Join-Hinweise und TF 4199

Keine JOIN-Hinweise und TF4199

Indizes

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) 
Mazhar
quelle
All diese Gewerkschaften. Könntest du nicht WO ... ODER ... ODER verwenden, anstatt diese Tabellen 4 Mal hintereinander zu treffen? Auch eine Möglichkeit, diese Funktion im Cross-Join loszuwerden? Auch, Sie müssen , dass MAXDOP Hinweis , es zu stoppen parallel gehen?
Rich Benner
1
Wenn ich den Plan richtig lese, sieht es so aus, als ob die FN_GetLocalTime_FromUTC_BasedOnTZIdFunktion dort ist, wo der Großteil der Zeit vergeht. Es sieht auch so aus, als würden die Werte dieser Funktion nur in der SELECTListe verwendet. Könnten Sie diese Funktion posten? Außerdem: Könnten Sie diese Datumstransformation nicht in der Funktion selbst ausführen, sondern direkt in der SELECTListe selbst ausführen (die Veröffentlichung der Funktion kann diese Frage beantworten)?
RDFozz
Sieht aus wie eine Leica-Datenbank. Wir hatten ein identisches Problem mit dem genau benannten UDF. Wir haben eine andere Methode verwendet, um in Ortszeit zu konvertieren und eine bessere Leistung zu erzielen.
Nick.McDermaid
@ Nick.McDermaid Dies ist keine Leica-Datenbank. Der Name der Funktion ist der gleiche ist nur ein Zufall
Mazhar
Entschuldigung, mein Fehler. Verwendet die Funktion Prozedurcode , um einen Zeitzonenversatz auf eine UTC-Zeit anzuwenden? Wie auch immer, wenn Sie es mit wenig Unterschied entfernt haben, spielt es wahrscheinlich keine Rolle
Nick.McDermaid

Antworten:

1

Wahrscheinlich kann Ihnen ein Clustered-Index über der temporären Tabelle #xMobiles beim letzten Join helfen

CREATE CLUSTERED INDEX IDX_xMobiles_VehicleKey ON #xMobiles
(
    VehicleKey ASC,
) 

Die beste Option ist, den Index nach dem Auffüllen der Tabelle zu erstellen.

Pablo Paredes
quelle
0

Diese Abfrage weist immer noch Fehler auf und ich kann sie nicht mit Ihren Daten testen. Würde dies jedoch zu denselben Ergebnissen führen und etwas schneller ausgeführt werden?

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 )
   ) 
Rich Benner
quelle
Der MAXDOP-Hinweis wird hinzugefügt, um zu verhindern, dass die Abfrage parallel verläuft. Ihre jüngste Änderung hat die Abfrage etwas verlangsamt. Außerdem ist die CROSS APPLy-Funktion erforderlich, und das Entfernen hat keinen Einfluss auf die Geschwindigkeit.
Mazhar