如何在SSIS作业中消除“未使用的输出列”警告?

时间:2008-11-05 21:38:39

标签: ssis logging

我正试图在我的SSIS进度日志中删除一些虚假警告。我在使用原始SQL来完成工作的任务中收到一堆关于未使用列的警告。我有一个数据流负责在加载新数据之前将数据存档到临时表中。数据流如下所示:

+--------------------+
| OLEDB Source task: |
| read staging table |
+--------------------+
          |
          |
+---------------------------+
| OLEDB Command task:       |
| upsert into history table |
+---------------------------+
          |
          |
+---------------------------+
| OLEDB Command task:       |
| delete from staging table |
+---------------------------+

我的'upsert'任务类似于:

--------------------------------------
-- 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
--------------------------------------

清理任务也是一个SQL命令:

--------------------------------------
delete from staging
--------------------------------------

由于upsert任务没有任何输出列定义,我在日志中收到一堆警告:

[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. 

如何消除对这些列的引用?我尝试过几个不同的任务,但似乎没有一个让我“吞下”输入列并将它们从任务的输出中抑制掉。我想保持我的日志清洁,所以我只看到真正的问题。有什么想法吗?

谢谢!

6 个答案:

答案 0 :(得分:5)

全部联盟 - 仅选择您要传递的列 - 删除任何其他列。

我认为他们将在2008版本中解决此问题,以允许从管道中修剪/抑制列。

答案 1 :(得分:2)

好的,我在MSDN forums上找到了解决方法:

在任务1和2之间使用脚本组件转换;选择所有输入列;将脚本体留空。

消耗列,正确处理作业并且不记录任何警告。

仍然不清楚为什么我需要OLEDB源,因为任务2中的SQL连接到源表并完成所有工作,但是当我删除OLEDB源时数据流运行但不处理任何行,因此,临时表永远不会被清空,然后由于PK违规而导致在staging表中放置已更改行的下游进程失败。但那是另一天的问题。这有点笨重,但我的日志很干净。

答案 2 :(得分:1)

管道中的警告是由数据源中选择的列未在任何后续任务中使用而引起的。

轻松解决此问题的方法是双击数据源。在你的情况下(OLEDB源任务:| | read staging table)然后单击列并取消选择任何未来任务项中不需要的列。

这将从进度日志中删除这些警告。

然而,阅读上面的项目并按照其他答案的说明,您没有使用后续项目中的“来源任务”中的列,因此可以将其删除。

答案 3 :(得分:1)

我有同样的问题。我收到了一个很好的答案。你可以找到它here

正如“Mark Wojciechowicz”所说:

以下是一些降低复杂性的建议,这反过来会提高性能:

  • 减少来源的列。如果要选择列 随后不以任何方式使用,然后从查询中删除它们 或者从源组件中取消选中它们。以这种方式删除列会从缓冲区中删除它们,这将占用更少的内存。
  • 减少数据流中的组件数量。很长的数据流很容易创建,测试很难,甚至难以维护。数据流期望工作单元,即从这里到那里的数据流,中间有一些东西。这就是数据流闪耀的地方,实际上,它们通过内存限制和最大线程数来保护自己免受复杂性的影响。最好将工作分成单独的数据流或存储过程。例如,您可以将数据分组到表中并读取两次,而不是使用多播。
  • 使用数据库。 SSIS既是一种编排工具,也是一种数据移动工具。我经常发现使用简单的数据流来分段数据,然后调用存储过程来处理数据,总是优于一体化数据流。
  • 增加写入数据的次数。这完全违反直觉,但如果您在较小的操作集中处理数据,则运行速度更快,更容易测试。给定一个干净的平板,我经常会设计一个ETL来将数据从源写入临时表,执行从阶段表到另一个阶段的清理步骤,可选地,添加一个符合步骤以将来自不同源的数据组合到另一个表和最后,加载目标表的最后一步。请注意,每个源都会被推送到自己的目标表,然后再利用数据库进行组合。第一步和最后一步设置为快速运行并避免在任一端锁定或阻塞。
  • 批量加载。当您确保发生批量装载时,前一步确实很好。这可能是一个棘手的事情,但通常你可以通过使用OLEDB目标中的“快速加载”和使用oledb命令的 never 来实现。删除索引并重新添加它们比在适当位置加载(除少数例外)更快。

答案 4 :(得分:0)

再次看你的问题,我认为你正在使用SSIS“反对谷物”。我并没有真正关注你从staging表中读取的内容,因为你的upsert似乎并不依赖于特定行中的任何内容,也不是清理。

在我看来,每行清理一次,但这没有用。

DataFlows通常不用于为管道中的每一行执行批量操作。如果您正在使用管道,则使用Lookup(或第三方TableDifference)组件处理UPSERT,然后将管道中的spli处理为OLEDB目标(BULK INSERT)和OLEDB命令(每个UPDATE一次)或另一个OLDEB目标。 “UPDATE临时表”。

通常,我会使用DataFlow来加载登台表而不进行任何拆分,然后在控制流中执行单个执行SQL任务,通过调用SP来执行直接SQL UPSERT中的所有其他操作(就像您一样)。 / p>

如果你不想拥有一个临时表,而不想读取一个平面文件并希望使用查找组件或其他东西执行UPDATE或INSERT,那么OLEDBCommand非常有用。但是它将在管道中的每一行被调用。

答案 5 :(得分:0)

你的DataFlow Task应该以“upsert”结束。然后返回控制流,创建一个Execute SQL Task,用于从暂存中删除。将您的DataFlow Task链接到您的exec sql。

我没有为我的upsert使用第三方工具,但是就像Cade所建议的那样,即将您的数据流拆分为新的记录,只需转到OLE DB Destination(或类似),并更新记录可以转到oledb命令进行更新。您可以使用合并连接或查找来拆分流。