为什么SQL参数嗅探会对首次执行产生负面的性能影响?

时间:2013-09-09 15:50:24

标签: tsql sql-server-2005 stored-procedures database-performance query-performance

我有一个SQL 2005数据库,它与大约250个不同位置的应用程序一起分发。在一个位置,存储过程超时。我发现存储过程中的查询在SSMS中自动运行,但是sproc需要30秒才能运行它。这让我开始阅读参数嗅探。文章&amp;我读过的论坛解释说,执行计划将根据第一次运行存储过程时使用的参数值创建,因此对于具有不同参数值的连续运行可能效率低下。说得通。我不明白的是,我已经删除并重新创建了存储过程(甚至尝试“重新编译”)并重新启动SQL Server,然后执行了sproc,它仍然需要30多秒才能在第一次运行和连续运行时运行< strong>每次使用相同的参数值。更新sproc以将参数值复制到本地变量确实修复它,但我不明白为什么当我只使用单个值并且所有参数嗅探示例都与使用多个相关时参数的值。当查询本身可以在不到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 param与局部变量时执行计划之间的差异。

enter image description here

tbl_EventBookingDate共有5635条记录,tbl_EventDateType中有5条记录。上部执行计划中的3,620和4,079,740恰好是每个表X 724中的记录数。而724是tbl_EventSchedule中的记录数,其中bs.eventdate&gt; @weekDate和bs.isdeleted = 0.所以当使用sproc参数时,它似乎是为每个tbl_EventSchedule行执行一次内部查询?

0 个答案:

没有答案