2013-07-31 43 views
0

我有一個填充SQL Server 2008 R2 DataWarehouse的SSIS包,當它從頭開始重新創建DW時,它會進行數百萬次調用一個存儲過程,在計算方面做了繁重的工作。SQL性能 - SSIS需要2分鐘來調用SProc,但SSMS需要<1秒

問題是SSIS包需要幾天才能運行,不應該花那麼長時間。關鍵似乎是,當SSIS包調用SProc時,SProc需要大約2分鐘才能返回結果。但是,如果我手動重新創建呼叫(在同一個數據庫上),則需要< 1秒才能返回結果,這正是我所期望的。

看到這個屏幕截圖,頂部是SQL Profiler Trace,顯示SSIS包的通話時間爲130秒,底部是我的通話重置,以1秒爲1秒的時間獲得<。

http://screencast.com/t/ygsGcdBV

存儲過程的查詢數據庫,通過與遊標結果迭代,確實在對記錄大量的計算,並amalgamates數量爲2分的結果,其得到恢復。

然而,手動調用的時間表明,這對於SProc本身並不是問題,或者是與數據庫本身有任何索引問題,那麼爲什麼SSIS包會比手動調用花費更多的時間呢?

任何提示理解。

感謝,

+0

很多在這裏的可能性。首先是參數嗅探,然後是不同的設置選項。明確的論文是[在應用程序慢,快於SSMS](http://www.sommarskog.se/query-plan-mysteries.html),但@PaulWhite對[慢存儲過程執行]更簡明的響應(HTTPS ://answers.sqlperformance.com/questions/346/slow-stored-proc-execution-on-log-shipping-seconda.html) – billinkc

回答

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 

在這一點上,你就會知道,您的查詢的一部分工作方式不同我猜你已經有了「啊哈」!未來。

+0

感謝您抽空回覆和尖端的時間。我知道一個遊標並不理想,但它通常只會迭代幾十行,而且通常非常快,這就是爲什麼當手動執行SProc時,它不到一秒鐘。對於使用臨時表的情況,我認爲我無法改進。 問題仍然是相同的代碼需要2分鐘SSIS調用時,我不知所措如何調試的原因着手。 – user2633679

0

我懷疑真正的問題是在你的存儲過程,但我已經包括了一些基本的SSIS項目,以及設法解決您的問題:

  • 確保連接管理器的OLE DB源都設置toDelayValidation (=真)。
  • 確保ValidateExternalMetadata設置爲false
  • DefaultBufferMaxRows和DefaultBufferSize對應表中的行大小
  • 刪除並重新創建目標組件是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 
0

這可能是很簡單的。驗證表中的索引。它可能是類似/衝突的索引,解決方案可能是放棄其中一個。 隨着SSMS的SQL查詢看看的執行計劃和索引對象使用。慢速SP是否一樣? 如果他們使用不同的索引嘗試使用SP中的快速索引。例如如何:

SELECT * 
FROM MyTable WITH (INDEX(IndexName)) 
WHERE MyIndexedColumn = 0 
相關問題