sql >> Database teknologi >  >> RDS >> Sqlserver

SSIS Package kører 500x længere på én server

Hvis du har aktiveret logning, helst til SQL Server, skal du tilføje hændelsen OnPipelineRowsSent. Du kan derefter bestemme, hvor den bruger al sin tid. Se dette indlæg Dit IO-undersystem bliver smækket og genererer alle disse midlertidige filer, fordi du ikke længere er i stand til at opbevare al information i hukommelsen (på grund af dine asynkrone transformationer).

Den relevante forespørgsel fra den linkede artikel er følgende. Den ser på hændelser i sysdtslog90 (SQL Server 2008+-brugere erstatter sysssislog ) og udfører nogle tidsanalyser på 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 var i stand til at bruge denne forespørgsel til at se, at Merge Join-komponenten var den haltende komponent. Hvorfor den fungerer forskelligt mellem de to servere, kan jeg ikke sige på nuværende tidspunkt.

Hvis du har mulighed for at oprette en tabel i dit destinationssystem, kan du ændre din proces til at have to 2 datastrømme (og eliminere de dyre asynkroniseringskomponenter).

  1. Det første dataflow ville tage kolonnerne Flade fil og Afledte og lande det i en iscenesættelsestabel.
  2. Du har derefter en Execute SQL-opgave udløst for at håndtere Get Min Date + Delete-logikken.
  3. Så har du dit andet dataflow, der forespørger fra din iscenesættelsestabel og snapper det direkte ind på din destination.


  1. Hvordan indsætter man en post og returnerer det nyoprettede ID ved hjælp af en enkelt SqlCommand?

  2. Brug af DATE_ADD med et kolonnenavn som intervalværdi

  3. Star vs Snowflake skema i data warehousing?

  4. Hvordan kommer man uden om en unik overtrædelse af begrænsninger?