sql >> Base de Datos >  >> RDS >> Sqlserver

El paquete SSIS se ejecuta 500 veces más en un servidor

Si tiene activado el registro, preferiblemente en SQL Server, agregue el evento OnPipelineRowsSent. A continuación, puede determinar dónde pasa todo su tiempo. Vea esta publicación Su subsistema IO se cierra de golpe y genera todos estos archivos temporales porque ya no puede mantener toda la información en la memoria (debido a sus transformaciones asíncronas).

La consulta relevante del artículo vinculado es la siguiente. Mira eventos en el sysdtslog90 (Los usuarios de SQL Server 2008+ sustituyen sysssislog ) y realiza un análisis de tiempo sobre ellos.

;
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.HoraInicio, Min(S.HoraInicio);

Pudo usar esta consulta para discernir que el componente Merge Join era el componente retrasado. Por qué funciona de manera diferente entre los dos servidores, no puedo decirlo en este momento.

Si tiene la capacidad de crear una tabla en su sistema de destino, puede modificar su proceso para tener dos 2 flujos de datos (y eliminar los costosos componentes asincrónicos).

  1. El primer flujo de datos tomaría el archivo sin formato y las columnas derivadas y las colocaría en una tabla de preparación.
  2. Luego tiene una tarea Ejecutar SQL activada para manejar la lógica Obtener fecha mínima + Eliminar.
  3. Luego tiene su segundo flujo de datos consultando desde su tabla de preparación y ajustándolo directamente a su destino.