我有一个 SQL 2005 数据库,它与一个应用程序一起分布在大约 250 个不同的位置。仅在一个位置,存储过程超时。我发现存储过程中的查询会在 SSMS 中自行即时运行,但存储过程需要 30 多秒才能运行它。这让我开始阅读参数嗅探。我读过的文章和论坛解释说,执行计划将根据您第一次运行存储过程时使用的参数值创建,因此对于使用不同参数值的连续运行可能效率低下。说得通。我不明白的是,我已经删除并重新创建了存储过程(甚至尝试过“重新编译”)并重新启动 SQL Server,然后执行存储过程,它仍然需要 30 多秒才能在第一次运行和连续运行时运行每次使用相同的参数值。更新存储过程以将参数值复制到局部变量确实可以修复它,但我不明白为什么当我只使用单个值并且所有参数嗅探示例都与使用多个参数值有关时。当查询本身可以在不到 0.01 秒内运行时,为什么它在这种情况下运行缓慢?
编辑:
这是查询:
SELECT bs.pk_EventScheduleID AS EventScheduleID,
bs.EventDate,
bs.EventDate AS [DisplayEventDate],
s.pk_StudentID AS [StudentID],
s.fk_FamilyID AS [FamilyID],
s.FirstName,
s.LastName,
bb.DepositDate,
[Step1],
[Step2],
[Step3],
[Step4],
[Step5],
'Required' AS [DatesType],
bb.IsCancelled
FROM tbl_EventSchedule bs
LEFT JOIN (tbl_EventBooking bb
INNER JOIN tbl_Student s ON bb.fk_StudentID = s.pk_StudentID
INNER JOIN (Select fk_EventBookingID,
[AADA95F3-23AA-40BE-9582-BA3847B88367] AS [Step1],
[F188F8A3-8F3C-429B-8F59-C510E1D94AA8] As [Step2],
[1E493583-3961-4ED0-9388-0D1AC4C0EF32] As [Step3],
[8E5E6B19-A863-4D03-BA97-1A2B86F71506] As [Step4],
[0FE5FDA7-DFEC-4E09-AC63-2805AC562AE3] As [Step5]
FROM (SELECT fk_EventBookingID, RequiredDate, GlobalTypeID
FROM tbl_EventBookingDate
INNER JOIN tbl_EventDateType ON fk_EventDateTypeID = pk_EventDateTypeID) t
PIVOT
(MAX(RequiredDate) FOR GlobalTypeID IN ([AADA95F3-23AA-40BE-9582-BA3847B88367],
[F188F8A3-8F3C-429B-8F59-C510E1D94AA8],
[1E493583-3961-4ED0-9388-0D1AC4C0EF32],
[8E5E6B19-A863-4D03-BA97-1A2B86F71506],
[0FE5FDA7-DFEC-4E09-AC63-2805AC562AE3])) As pvt
) bbdRequired
ON bb.pk_EventBookingID = bbdRequired.fk_EventBookingID
)ON bs.pk_Eventscheduleid = bb.fk_Eventscheduleid
WHERE bs.eventdate > @weekDate
AND bs.isdeleted = 0
AND (bb.pk_EventBookingID IS NULL OR
(
bb.IsDeleted = 0
-- AND bb.IsCancelled = 0
)
)
执行时,第一步是 tbl_EventBookingDate 和 tbl_EventDateType 之间的最内表连接。查看使用 sproc 参数与局部变量时执行计划之间的差异。
tbl_EventBookingDate 共有 5635 条记录,tbl_EventDateType 有 5 条记录。上层执行计划中的 3,620 和 4,079,740,恰好是每个表中的记录数 X 724。而 724 是 tbl_EventSchedule 中的记录数,其中 bs.eventdate > @weekDate 和 bs.isdeleted = 0。所以看起来是使用 sproc 参数时为每个 tbl_EventSchedule 行执行一次内部查询?