2015-05-06 79 views
1

當我對服務器生產(8核心)上的數據庫執行SQL查詢時,大約需要7秒鐘才能獲得2244行。執行存儲過程的長延遲

我有一個存儲過程與以前的SQL查詢相同,當我對我的數據庫執行它時,大約需要1分20秒才能獲得相同的2244行。

我有一個表值函數具有相同的SQL查詢,當我對我的數據庫執行它時,大約需要1分20秒才能得到相同的2244行。

因此:
SQL查詢:7秒
存儲過程:1分20秒。
表值功能:1分20秒。

現在最離奇的一部分:

測試服務器(4個核)使用相同的數據庫上相同的情況下,我得到以下成績:

SQL查詢:1分20秒。
存儲過程:7秒。
表值功能:7秒。

有什麼我忘記了,這會導致很長的延遲?

+0

請問您的2存儲過程的查詢到你的問題? –

+0

嗨@JohnOdom,據我解釋,只有一個存儲過程。我無法發佈SQL查詢,因爲企業策略。 –

+0

嗯...你嘗試過使用CLR集成嗎?我剛剛從[這個問題](http://stackoverflow.com/questions/4603396/what-is-extended-stored-procedure-in-ms-sql-server)讀取擴展存儲過程已被棄用,應該避免如果可能。 –

回答

4

從我的經驗
1)嘗試在使用前將你的參數放入局部變量。

create procedure [dbo].[usp_test](@Id varchar(20)) 
as 
begin 
    select * from Test 
    where Id = @Id 
end 

alter procedure [dbo].[usp_test](@Id varchar(20)) 
as 
begin 
    declare @local_id varchar(20) = @Id 

    select * from Test 
    where Id = @local_id 
end 

2)使用重新編譯提示。這將得到更適合基於參數值的查詢的新查詢計劃。

exec dbo.usp_test 1 with recompile 

參考
https://technet.microsoft.com/en-us/library/ms190439%28v=sql.105%29.aspx
http://www.sqlpointers.com/2006/11/parameter-sniffing-stored-procedures.html

+0

當我在SQL查詢中直接使用選項(重新編譯)時,執行時需要1分20秒它。當我在存儲過程中使用「重新編譯」提示時,執行它需要1分20秒。 可能是執行長延遲任務的重新編譯操作? –

1

長時間的測試和研究之後,我真的認爲這是嗅探問題的參數,因爲我也做了以下測試:

執行SQL正常查詢:7秒。

declare @field_1 int = 1 
declare @field_2 NVARCHAR(MAX) = null 
declare @field_3 NVARCHAR(MAX) = null 
declare @field_4 NVARCHAR(MAX) = null 
declare @field_5 NVARCHAR(MAX) = null 
declare @field_6 NVARCHAR(MAX) = null 
declare @field_7 NVARCHAR(MAX) = null 
declare @field_8 DATE = dateadd(month, -1, getdate()) 
declare @field_9 DATE = getdate() 
select * ... 

執行TVF這樣:7秒

declare @field_1 int = 1 
declare @field_2 NVARCHAR(MAX) = null 
declare @field_3 NVARCHAR(MAX) = null 
declare @field_4 NVARCHAR(MAX) = null 
declare @field_5 NVARCHAR(MAX) = null 
declare @field_6 NVARCHAR(MAX) = null 
declare @field_7 NVARCHAR(MAX) = null 
declare @field_8 DATE = dateadd(month, -1, getdate()) 
declare @field_9 DATE = getdate() 

select * 
from fn_generar_reporte_cred(@field_1, @field_2, @field_3, @field_4, @field_5, 
@field_6, @field_7, @field_8, @field_9) 

執行TVF是這樣的:1分20秒

select * 
from fn_generar_reporte_cred(1, null, null, null, null, null, null, dateadd(month, -1, getdate()), getdate()) 

執行SP通常:1分20秒

CREATE PROCEDURE [dbo].[pa_reporte_cred](
    @field_1 INT, 
    @field_2 NVARCHAR(MAX), 
    @field_3 NVARCHAR(MAX), 
    @field_4 NVARCHAR(MAX), 
    @field_5 NVARCHAR(MAX), 
    @field_6 NVARCHAR(MAX), 
    @field_7 NVARCHAR(MAX), 
    @field_8 DATE, 
    @field_9 DATE 
) AS 
BEGIN 
SELECT * ... 

Execute SP normall y(內部改變):7秒

CREATE PROCEDURE [dbo].[pa_reporte_cred_ss](
    @field_1_ss INT, 
    @field_2_ss NVARCHAR(MAX), 
    @field_3_ss NVARCHAR(MAX), 
    @field_4_ss NVARCHAR(MAX), 
    @field_5_ss NVARCHAR(MAX), 
    @field_6_ss NVARCHAR(MAX), 
    @field_7_ss NVARCHAR(MAX), 
    @field_8_ss DATE, 
    @field_9_ss DATE 
) AS 
BEGIN 
declare @field_1 int 
declare @field_2 NVARCHAR(MAX) 
declare @field_3 NVARCHAR(MAX) 
declare @field_4 NVARCHAR(MAX) 
declare @field_5 NVARCHAR(MAX) 
declare @field_6 NVARCHAR(MAX) 
declare @field_7 NVARCHAR(MAX) 
declare @field_8 DATE 
declare @field_9 DATE 
SELECT @field_1 = @field_1_ss, @field_2 = @field_2_ss, @field_3 = @field_3_ss, 
    @field_4 = @field_4_ss, @field_5 = @field_5_ss, @field_6 = @field_6_ss, 
    @field_7 = @field_7_ss, @field_8 = @field_8_ss, @field_9 = @field_9_ss 
SELECT * ... 

謝謝大家的幫助!