SQL性能 - SSIS需要2分钟来调用SProc,但SSMS需要<1秒

时间:2013-07-31 10:59:47

标签: performance stored-procedures ssis sql-server-2008-r2

我有一个填充SQL Server 2008 R2 DataWarehouse的SSIS包,当它从头开始重新创建DW时,它会对存储过程进行数百万次调用,从而在计算方面做得很重。

问题是SSIS包需要几天才能运行,不应该花那么长时间。关键似乎是当SSIS包调用SProc时,SProc大约需要2分钟才能返回结果。但是如果我手动重新创建调用(在同一个数据库上),则返回结果需要<1秒,这就是我所期望的。

参见此屏幕截图,顶部是SQL Profiler Trace,显示SSIS包的呼叫需要130秒,而在底部是我重新启动呼叫,花费时间<1秒。

http://screencast.com/t/ygsGcdBV

SProc查询数据库,使用游标迭代结果,对记录对进行大量计算,并将数字合并为2个返回的结果。

然而,手动调用的时间,对我来说,这不是SProc本身的问题,也不是数据库本身的任何索引问题,那么为什么SSIS包比手动调用花费的时间长得多? / p>

任何提示都表示赞赏。

谢谢,

3 个答案:

答案 0 :(得分:0)

我没有适合您的解决方案,但我确实有一个建议和程序可以帮助您获得解决方案的更多信息。

建议:被调用数百万次的存储过程不应该使用游标。通常,游标可以由几个语句和临时表替换。对于行数超过10k的临时表,请将其编入索引。

程序:在存储过程中的关键位置放置一个声明

declare @timer1 datetime = GetDate()
(some code)
declare @timer2 datetime = GetDate()
(more code)
declare @timer3 datetime = GetDate()

然后,最后:

select 
datediff(ss,@timer1,@timer2) as Action1,
datediff(ss,@timer2,@timer3) as Action2

此时,您将知道查询的哪个部分的工作方式不同。我猜你有一个“啊哈!”来了。

答案 1 :(得分:0)

我怀疑真正的问题出在您的存储过程中,但我还提供了一些基本的SSIS项目来尝试解决您的问题:

  • 确保OLE DB源的连接管理器都设置为DelayValidation(= True)。
  • 确保ValidateExternalMetadata设置为false
  • DefaultBufferMaxRows和DefaultBufferSize对应表的行大小
  • DROP并重新创建目标组件是SSIS
  • 在存储过程中确保SET ANSI_NULLS ON
  • 确保您的sproc中的SQL命中索引
  • 添加查询提示OPTION(FAST 10000) - 此提示表示它将选择一个优化前10,000行的查询 - 默认SSIS缓冲区大小

  • 检查存储过程SQL Server parameter sniffing

缓慢的方式:

create procedure GetOrderForCustomers(@CustID varchar(20))
as
begin
  select * from orders
  where customerid = @CustID
end

快捷方式:

create procedure GetOrderForCustomersWithoutPS(@CustID varchar(20))
as
begin
  declare @LocCustID varchar(20)
  set @LocCustID = @CustID

  select * from orders
  where customerid = @LocCustID
end

答案 2 :(得分:0)

这可能很简单。验证表中的索引。它可能是类似/冲突的索引,解决方案可能是删除其中一个。 使用SSMS中的SQL查询可以查看执行计划以及使用的索引对象。缓慢的SP是否相同? 如果他们使用不同的索引,请尝试在SP中使用快速索引。示例如何:

SELECT *
FROM MyTable WITH (INDEX(IndexName))
WHERE MyIndexedColumn = 0