我正在研究一个流量很大的数据库,有时一个 SP(存储过程)的持续时间为 382656 毫秒,但 SP 是一个简单的操作,而其他时间(使用相同的参数)有一个持续时间 200 毫秒。我使用了一个分析器工具并对此进行了调查,在第一种情况下(382656ms),有大约 12 万次读取。第 2 次(前几天)有 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 语句上使用 With nolock ...
谢谢!
已编辑
感谢约翰的回复。“首先检查参数。也许第一个查询的日期范围很大”我使用相同的参数来检查这一点。
“检查一下这种波动是否可重复。” 它发生在ramndon,
“检查表数据是否发生了巨大变化。” 该表每天增加了900万条记录,但是对于不同的idc,所以对于相同的参数,idc只有数据的更新
“检查是否有人创建了减少必要读取次数的索引。” 不
“检查统计信息是否已更新,以便使用正确的索引。” 不,它总是使用正确的索引。
“检查查询计划是否已刷新。” 当 SP 失败时,我必须制定一个执行计划。我试过但总是使用正确的索引并且执行计划没问题。
编辑 2:运行一些测试并查看活动监视器后,我看到 PAGEIOLATCH_SH 等待。但是,当从 web 应用程序执行 sp 时,总是会发生这种等待。在 Web 应用程序中进行测试,加载一个我知道运行 SP 并且知道参数的页面,当 sp 等待 PAGEIOLATCH_SH 时,我在 SQL 管理上执行了相同的 sp,并在 0 秒内返回结果。而 web 应用程序的 sp 仍在等待。
为什么会这样??