当我针对服务器生产(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 :(得分: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 * ...
谢谢大家的帮助!