执行存储过程的延迟很长

时间:2015-05-06 21:08:22

标签: sql-server

当我针对服务器生产(8核)上的数据库执行SQL查询时,需要大约7秒才能获得2244行。

我有一个存储过程与之前的SQL查询相同,当我对我的数据库执行它时,需要大约1分20秒来获得相同的2244行。

我有一个具有相同SQL查询的表值函数,当我对我的数据库执行它时,需要大约1分20秒来获得相同的2244行。

所以:
SQL查询:7秒
存储过程:1分20秒。
表值功能:1分20秒。

现在最奇怪的部分:

在具有相同数据库的测试服务器(4个核心)上的相同场景,我得到以下分数:

SQL查询:1分20秒。
存储过程:7秒。
表值函数:7秒。

是否有一些我忘记的事情,这会造成长时间的拖延?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 * ...

正常执行SP(内部更改):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 * ...

谢谢大家的帮助!