2015-05-06 154 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 * ... 

谢谢大家的帮助!