我正在研究一个拥有大量流量的数据库,并且有时候一个SP(存储过程)的持续时间为382656ms,但SP很容易在其他时间运行(具有相同的参数) )持续时间为200毫秒。我使用了一个分析器工具并研究了这个,在第一种情况下(382656ms),有大约12毫安的读数。第二天(在另一天)有215个读数。
SP是这样的:
ALTER PROCEDURE [dbo].[MySP] @Id INT,
@StartDate DATETIME,
@EndDate DATETIME,
@StatusID int
AS
SET @StartDate = CONVERT(DATETIME, CONVERT(VARCHAR(10), @StartDate, 101),
101)
SET @EndDate = Dateadd(dd, 1, @EndDate)
SET @EndDate = CONVERT(DATETIME, CONVERT(VARCHAR(10), @EndDate, 101), 101)
SELECT t3.name,
t3.code,
Sum(cdoi.count) Cout1,
Sum(Isnull(S.cant, 0)) AS Count2
FROM table1 t1 WITH(nolock)
JOIN dbo.table2 t2 WITH(nolock)
ON t1.lid = t2.lid
JOIN table3 t3 WITH(nolock)
ON t3.coid = t2.coid
LEFT JOIN (SELECT t4.ids,
t5.idc,
Sum(t4.count) AS Count2
FROM table4 t4 WITH(nolock)
INNER JOIN table5 t5 WITH(nolock)
ON t5.idlink = t4.idlink
WHERE t5.IdC = @Idc
GROUP BY t4.ids,
t5.idc) S
ON S.ids = t1.ids
AND S.idc = t1.idc
WHERE t1.Idc = @Idc
AND t1.StatusID = @StatusID
AND [date] BETWEEN @StartDate AND @EndDate
GROUP BY t3.name,
t3.code
任何人都知道为什么会发生这种情况?
请注意,我在select语句中使用了nolock ...
谢谢!
EDITED
感谢John的回复。 “首先检查参数。也许第一个查询有一个巨大的日期范围” 我用相同的参数来检查这个。
“检查这种波动是否可重复。” 它发生了ramndon,
“检查表格数据是否发生了巨大变化。” 该表每天增加9百万条记录,但对于不同的idc,所以对于相同的参数,Idc只有数据更新
“检查是否有人创建了一个索引,减少了必要的读取次数。” 否
“检查统计信息是否已更新,以便使用正确的索引。” 不,它始终使用正确的索引。
“检查查询计划是否已刷新。” 当SP失败时,我要赶上一个执行计划。我已经尝试但总是使用正确的索引,而且执行计划还可以。
编辑2: 运行一些测试并查看活动监视器后,我看到了PAGEIOLATCH_SH等待。但是,当从Web应用程序执行sp时,总会发生这种等待。在Web应用程序中测试,加载我知道运行SP的页面并且还知道参数,当sp等待PAGEIOLATCH_SH时,我在SQL Management上执行相同的sp并在0秒内返回结果。虽然网络应用程序的sp仍在等待。
为什么会这样?