【问题标题】:SSIS Performance drop when adding parameters添加参数时 SSIS 性能下降
【发布时间】:2013-08-08 12:35:35
【问题描述】:

我在 SSIS 中使用 OLE DB 源从 SQL Server 2012 数据库中提取数据行:

SELECT item_prod.wo_id, item_prod.oper_id, item_prod.reas_cd, item_prod.lot_no, item_prod.item_id, item_prod.user_id, item_prod.seq_no, item_prod.spare1, item_prod.shift_id, item_prod.ent_id, item_prod.good_prod, item_cons.lot_no as raw_lot_no, item_cons.item_id as rm_item_id, item_cons.qty_cons
FROM item_prod
LEFT OUTER JOIN item_cons on item_cons.wo_id=item_prod.wo_id AND item_cons.oper_id=item_prod.oper_id AND item_cons.seq_no=item_prod.seq_no AND item_prod.lot_no=item_cons.fg_lot_no

这很好用,目前每分钟可以提取大约 100 万行。由于在不使用缓存时性能要好得多,因此使用左外连接而不是查找,并且两个表可能包含超过 4000 万行。

我们需要查询仅拉取上一次运行中未拉取的行。最后一次运行的 row_id 存储在一个变量中,并放在上述查询的末尾:

WHERE item_prod.row_id > ?

在第一次运行时,参数将为 -1(解析所有内容)。 通过添加 where 子句,性能下降 5-10 倍(每 5-10 分钟 100 万行)。是什么导致了如此显着的性能下降,有没有办法对其进行优化?

【问题讨论】:

  • 比较执行计划。我认为它们是不同的。我会考虑使您的过滤器动态化并在初始加载时禁用它(参数 = -1),否则启用它

标签: sql-server performance ssis


【解决方案1】:

事实证明,SSIS 在执行带参数的查询时会创建一个存储过程。这是通过查看 SQL Server Profiler 中的执行发现的。

因此,性能受到了影响,我相信是related to parameter sniffing

我将源更改为使用 SQL Query from Variable,并改为使用表达式构建查询,这修复了性能。

编辑:以下是使用where参数执行问题代码时在SQL Server Profiler中看到的命令:

exec [sys].sp_describe_undeclared_parameters N'SELECT item_prod.wo_id, item_prod.oper_id, item_prod.reas_cd, item_prod.lot_no, item_prod.item_id, item_prod.user_id, item_prod.seq_no, item_prod.spare1, item_prod.shift_id, item_prod.ent_id, item_prod.good_prod, item_cons.lot_no as raw_lot_no, item_cons.item_id as rm_item_id, item_cons.qty_cons
FROM item_prod
LEFT OUTER JOIN item_cons on item_cons.wo_id=item_prod.wo_id AND item_cons.oper_id=item_prod.oper_id AND item_cons.seq_no=item_prod.seq_no AND item_prod.lot_no=item_cons.fg_lot_no
WHERE item_prod.row_id > @P1'

declare @p1 int
set @p1=1
exec sp_prepare @p1 output,N'@P1 int',N'SELECT item_prod.wo_id, item_prod.oper_id, item_prod.reas_cd, item_prod.lot_no, item_prod.item_id, item_prod.user_id, item_prod.seq_no, item_prod.spare1, item_prod.shift_id, item_prod.ent_id, item_prod.good_prod, item_cons.lot_no as raw_lot_no, item_cons.item_id as rm_item_id, item_cons.qty_cons
FROM item_prod
LEFT OUTER JOIN item_cons on item_cons.wo_id=item_prod.wo_id AND item_cons.oper_id=item_prod.oper_id AND item_cons.seq_no=item_prod.seq_no AND item_prod.lot_no=item_cons.fg_lot_no
WHERE item_prod.row_id > @P1',1
select @p1

exec [sys].sp_describe_first_result_set N'SELECT item_prod.wo_id, item_prod.oper_id, item_prod.reas_cd, item_prod.lot_no, item_prod.item_id, item_prod.user_id, item_prod.seq_no, item_prod.spare1, item_prod.shift_id, item_prod.ent_id, item_prod.good_prod, item_cons.lot_no as raw_lot_no, item_cons.item_id as rm_item_id, item_cons.qty_cons
FROM item_prod
LEFT OUTER JOIN item_cons on item_cons.wo_id=item_prod.wo_id AND item_cons.oper_id=item_prod.oper_id AND item_cons.seq_no=item_prod.seq_no AND item_prod.lot_no=item_cons.fg_lot_no
WHERE item_prod.row_id > @P1',N'@P1 int',1

由于我不完全确定上面生成的代码是做什么的,因此我可能遗漏了其他相关命令。最初,我假设 SSIS 变量会被插入到查询中,但 @P1 参数的引入让我转而研究存储过程的含义。

【讨论】:

  • 您能否提供一个参考,SSIS 在哪里创建存储过程?我在引用的文章中没有看到这一点
  • @billinkc 这不是文章的一部分,只有在发现正在执行存储过程(而不是插入变量的查询,这是我所期望的)之后,文章才相关。我将重现结果并更新我的答案。
  • @billinkc 我已经添加了探查器结果。我很想听听你对这是否正确的看法,因为我是 SSIS 的新手。
猜你喜欢
  • 2014-05-27
  • 2020-11-28
  • 2018-10-21
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多