sql >> Databasteknik >  >> RDS >> Sqlserver

SSIS Package körs 500 gånger längre på en server

Om du har inloggning aktiverad, helst till SQL Server, lägg till händelsen OnPipelineRowsSent. Du kan sedan bestämma var den spenderar all sin tid. Se detta inlägg Ditt IO-undersystem får smäll och genererar alla dessa temporära filer beror på att du inte längre kan behålla all information i minnet (på grund av dina asynkrona transformationer).

Den relevanta frågan från den länkade artikeln är följande. Den tittar på händelser i sysdtslog90 (SQL Server 2008+-användare ersätter sysssislog ) och utför en viss tidsanalys av dem.

;
WITH PACKAGE_START AS
(
    SELECT DISTINCT
        Source
    ,   ExecutionID
    ,   Row_Number() Over (Order By StartTime) As RunNumber
    FROM
        dbo.sysdtslog90 AS L
    WHERE
        L.event = 'PackageStart'
)
, EVENTS AS
(
    SELECT
        SourceID
    ,   ExecutionID
    ,   StartTime
    ,   EndTime
    ,   Left(SubString(message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, 56) + 1) + 1) + 1) + 2, Len(message)), CharIndex(':', SubString(message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, 56) + 1) + 1) + 1) + 2, Len(message)) ) - 2) As DataFlowSource
    ,   Cast(Right(message, CharIndex(':', Reverse(message)) - 2) As int) As RecordCount
    FROM
        dbo.sysdtslog90 AS L
    WHERE
        L.event = 'OnPipelineRowsSent'
)
, FANCY_EVENTS AS
(
    SELECT
        SourceID
    ,   ExecutionID
    ,   DataFlowSource
    ,   Sum(RecordCount) RecordCount
    ,   Min(StartTime) StartTime
    ,   (
            Cast(Sum(RecordCount) as real) /
            Case
                When DateDiff(ms, Min(StartTime), Max(EndTime)) = 0
                    Then 1
                Else DateDiff(ms, Min(StartTime), Max(EndTime))
            End
        ) * 1000 As RecordsPerSec
    FROM
        EVENTS DF_Events
    GROUP BY
        SourceID
    ,   ExecutionID
    ,   DataFlowSource
)
SELECT
    'Run ' + Cast(RunNumber As varchar) As RunName
,   S.Source
,   DF.DataFlowSource
,   DF.RecordCount
,   DF.RecordsPerSec
,   Min(S.StartTime) StartTime
,   Max(S.EndTime) EndTime
,   DateDiff(ms, Min(S.StartTime)
,   Max(S.EndTime)) Duration
FROM
    dbo.sysdtslog90 AS S
    INNER JOIN
        PACKAGE_START P
        ON S.ExecutionID = P.ExecutionID
    LEFT OUTER JOIN
        FANCY_EVENTS DF
        ON S.SourceID = DF.SourceID
        AND S.ExecutionID = DF.ExecutionID
WHERE
    S.message <> 'Validating'
GROUP BY
    RunNumber
,   S.Source
,   DataFlowSource
,   RecordCount
,   DF.StartTime
,   RecordsPerSec
,   Case When S.Source = P.Source Then 1 Else 0 End
ORDER BY
    RunNumber
,   Case When S.Source = P.Source Then 1 Else 0 End Desc

, DF.StartTime, Min(S.StartTime);

Du kunde använda den här frågan för att se att Merge Join-komponenten var den eftersläpande komponenten. Varför den fungerar olika mellan de två servrarna kan jag inte säga i nuläget.

Om du har möjlighet att skapa en tabell i ditt målsystem kan du modifiera din process så att den har två 2 dataflöden (och eliminera de kostsamma asynkronkomponenterna).

  1. Det första dataflödet skulle ta kolumnerna Flat file och Derived och landa det i en iscensättningstabell.
  2. Du har sedan en Execute SQL Task avstängd för att hantera logiken Get Min Date + Delete.
  3. Då har du ditt andra dataflöde att fråga från din mellanställningstabell och knäppa det direkt till din destination.


  1. MySQL – Återställ databas för tappad prestandaschema

  2. IntegrityError:(1062, dubblettpost för nyckel)

  3. Ansluta till MySQL-databasen med PHP från en Android-enhet

  4. Hur man gör enkelt CRUD med PHP och MySQL enkelt