practices - ¿Cómo eliminar las advertencias de ''columna de salida no utilizada'' en trabajos SSIS?
ssis logging best practices (6)
Union All: seleccione solo las columnas por las que desea pasar, elimine las demás.
Pensé que abordarían esto en la versión de 2008 para permitir que las columnas se recorten / supriman desde la canalización.
Estoy tratando de deshacerme de algunas advertencias falsas en mi registro de progreso de SSIS. Recibo muchas advertencias sobre columnas no utilizadas en tareas que usan SQL sin formato para hacer su trabajo. Tengo un flujo de datos responsable de archivar datos en una tabla de etapas antes de cargar nuevos datos. El flujo de datos se ve así:
+--------------------+
| OLEDB Source task: |
| read staging table |
+--------------------+
|
|
+---------------------------+
| OLEDB Command task: |
| upsert into history table |
+---------------------------+
|
|
+---------------------------+
| OLEDB Command task: |
| delete from staging table |
+---------------------------+
mi tarea ''upsert'' es algo así como:
--------------------------------------
-- update existing rows first...
update history
set field1 = s.field1
...
from history h
inner join staging s
on h.id = s.id
where h.last_edit_date <> s.last_edit_date -- only update changed records
-- ... then insert new rows
insert into history
select s.*
from staging s
join history h
on h.id = s.id
where h.id is null
--------------------------------------
La tarea de limpieza es también un comando SQL:
--------------------------------------
delete from staging
--------------------------------------
Como la tarea upsert no tiene definiciones de columna de salida, recibo un montón de advertencias en el registro:
[DTS.Pipeline] Warning: The output column "product_id" (693) on output
"OLE DB Source Output" (692) and component "read Piv_product staging table" (681)
is not subsequently used in the Data Flow task. Removing this unused output column
can increase Data Flow task performance.
¿Cómo puedo eliminar las referencias a esas columnas? He intentado incluir algunas tareas diferentes, pero ninguna de ellas me permite "tragar" las columnas de entrada y suprimirlas de la salida de la tarea. Me gustaría mantener mis registros limpios, así que solo veo problemas reales. ¿Algunas ideas?
¡Gracias!
OK, tengo una solución en los foros de MSDN :
utilizar una transformación de componente de script entre las tareas 1 y 2; seleccione todas las columnas de entrada; deja el cuerpo de la secuencia de comandos vacío.
Eso consume las columnas, el trabajo se procesa correctamente y no se registran las advertencias.
Aún no está claro por qué necesito la fuente OLEDB en absoluto, ya que el SQL en la tarea 2 se conecta a las tablas fuente y hace todo el trabajo, pero cuando elimino la fuente OLEDB, el flujo de datos se ejecuta pero no procesa ninguna fila, por lo que la tabla nunca se vacía, y luego el proceso descendente para poner filas cambiadas en la tabla provisional falla debido a violaciones de PK. Pero ese es un problema para otro día. Esto es un poco torpe, pero mis registros están limpios.
Mirando su problema nuevamente, creo que está usando SSIS "contra la corriente". Realmente no estoy siguiendo lo que está leyendo de la tabla de etapas, ya que su upsert no parece depender de nada en una fila en particular, ni tampoco la limpieza.
Me parece que la limpieza se ejecutará una vez por cada fila, pero eso realmente no tiene sentido.
DataFlows generalmente no se utilizan para realizar acciones masivas para cada fila que se envía por la tubería. Si está utilizando un pipeline UPSERTs se manejan utilizando los componentes Lookup (o TableDifference de terceros) y luego un spli en la tubería a un destino OLEDB (BULK INSERT) y un comando OLEDB (una vez por UPDATE) u otro destino OLDEB para un "ACTUALIZAR la tabla de etapas".
Normalmente, haría esto con un DataFlow para cargar la tabla de etapas sin ninguna división, luego una única tarea de ejecución de SQL en el flujo de control para realizar todo lo demás en SQL UPSERT (como la que tiene) directamente llamando a un SP.
OLEDBCommand es útil si NO QUIERES tener una tabla de etapas y, en su lugar, leer un archivo plano y desea ejecutar UPDATE o INSERT utilizando un componente de búsqueda o algo así. Pero se llamará para cada fila en la tubería.
Las advertencias en su canalización son causadas por columnas seleccionadas en su fuente de datos que no se están utilizando en ninguna Tarea posterior.
La solución más sencilla es hacer doble clic en su fuente de datos. En su caso (OLEDB Source task: | | read staging table) A continuación, haga clic en las columnas y anule la selección de las columnas que no necesite en ninguno de sus futuros elementos de tareas.
Esto eliminará esas advertencias de su registro de progreso.
Sin embargo, al leer su artículo anterior y según lo explicado por otras respuestas, no está utilizando las columnas de la tarea de origen en los elementos siguientes, por lo que simplemente puede eliminarse.
Su DataFlow Task
debe terminar con el "upsert". A continuación, vuelva al flujo de control y cree una Execute SQL Task
de Execute SQL Task
para la eliminación de la transición. Enlace su DataFlow Task
a su ejecutivo sql.
No utilizo una herramienta de terceros para mis sugerencias, pero hago lo que sugiere Cade, que es dividir su flujo de datos en nuevos registros que se dirigen a un OLE DB Destination
(o similar), y actualizar los registros que pueden ir a su oledb comando para actualizaciones. Puede dividir el flujo usando una combinación de fusión o una búsqueda.
Tengo la misma pregunta. He recibido una buena respuesta. Puedes encontrarlo aquí .
Como dijo " Mark Wojciechowicz ":
Aquí hay algunas recomendaciones para reducir la complejidad, lo que, a su vez, mejorará el rendimiento:
- Reduce las columnas en la fuente. Si está seleccionando columnas que no se utilizan posteriormente de ninguna manera, elimínelas de la consulta o desmárquelas del componente fuente. Al eliminar columnas de esta forma, se eliminan del búfer, lo que ocupará menos memoria.
- Reduzca la cantidad de componentes en el flujo de datos . Flujos de datos muy largos son fáciles de crear, un dolor de prueba e incluso más difícil de mantener. Los flujos de datos esperan una unidad de trabajo , es decir, un flujo de datos de aquí para allá con algunas cosas en el medio. Aquí es donde brillan los flujos de datos, de hecho, se protegen de la complejidad con limitaciones de memoria y un número máximo de hilos. Es mejor dividir el trabajo en flujos de datos separados o procesos almacenados. Puede organizar los datos en una tabla y leerlos dos veces, en lugar de utilizar una multidifusión, por ejemplo.
- Usa la base de datos SSIS es tanto una herramienta de orquestación como una herramienta de movimiento de datos. A menudo he encontrado que el uso de flujos de datos simples para organizar los datos , seguido de llamadas a procedimientos almacenados para procesar los datos , siempre supera el flujo de datos todo en uno.
- Aumenta la cantidad de veces que escribes los datos . Esto es totalmente contrario a la intuición, pero si procesa datos en conjuntos más pequeños de operaciones, se ejecuta más rápido y es más fácil de probar. Dado un borrón y cuenta nueva, a menudo diseñaré un ETL para escribir datos de la fuente en una tabla de etapas, realizar un paso de limpieza de la tabla de etapas a otra, opcionalmente, agregar un paso conforme para combinar datos de diferentes fuentes a otra tabla y , finalmente, un último paso para cargar una tabla objetivo. Tenga en cuenta que cada fuente se envía a su propia tabla de destino y luego se combina, aprovechando la base de datos. El primer y el último paso están configurados para ejecutarse rápidamente y evitar bloqueos o bloqueos en cualquier extremo.
- Carga a granel . El paso anterior realmente funciona bien, cuando usted asegura que la carga masiva está sucediendo. Esto puede ser algo complicado, pero en general se puede llegar utilizando "carga rápida" en el destino OLEDB y nunca utilizando el comando oledb. Eliminar índices y volverlos a agregar es más rápido que cargarlos en su lugar (con algunas excepciones).