所以基本上我有这个相对较长的存储过程。 基本执行流程是,它SELECTS INTO
一些数据与他宣布临时表#
符号,然后通过这些表运行的游标产生一个“运行总计”到被使用创建第三个临时表CREATE
。 那么这导致临时表是在数据库与其它表连接,以产生一些分组之后的结果等等的问题是,这个SP已直到1-2分钟,现在返回结果运行良好。 现在突然其采取12-15分钟。 如果我提取从SP查询,并通过手动设置相同的参数,它返回在1-2分钟内的结果,但在SP需要很长执行它在管理工作室。 任何想法可能会发生。 我试图同时生成查询和SP的实际执行计划,但它不能生成因为游标的它。 任何想法,为什么SP这么久,而查询不?
Answer 1:
这是参数嗅探的足迹。 在这里看到关于它的另一个讨论; SQL可怜的存储过程的执行计划性能-参数嗅探
有几种可能的解决方法,包括增加WITH RECOMPILE到工作半个月左右的时间你的存储过程。
在大多数情况下推荐的修复(尽管它取决于你的查询和存储过程的结构)是不能直接在查询中使用的参数,而是将它们存储到本地变量,然后在查询中使用这些变量。
Answer 2:
其由于参数嗅探。 首先声明临时变量和设定输入变量值的临时变量和在整个程序中使用临时变量这里是下面一个例子。
ALTER PROCEDURE [dbo].[Sp_GetAllCustomerRecords]
@customerId INT
AS
declare @customerIdTemp INT
set @customerIdTemp = @customerId
BEGIN
SELECT *
FROM Customers e Where
CustomerId = @customerIdTemp
End
试试这个方法
Answer 3:
我也想看看参数嗅探。 可能是PROC需要处理的参数slighlty不同。
Answer 4:
尝试重新编译存储过程的抛弃任何存储的查询计划
exec sp_recompile 'YourSproc'
然后运行存储过程并注意使用合理的paramters。
也比较执行查询的两种方法之间的实际执行计划。
这也可能是值得重新计算任何统计数据。
Answer 5:
我通常用“‘ - 步’打印GETDATE()+”开始这样的故障排除问题。 这有助于我缩小什么是最耗时。 您可以从您从查询分析器运行它比较和缩小问题的所在处。
Answer 6:
我想这可能可以下降到缓存。 如果您运行存储过程两次是更快的第二次?
为了进一步研究,你可以从两个Management Studio中的存储过程,并与节目查询计划选项查询版本管理工作室打开运行它们,然后进行比较时,作为查询运行存储过程正在采取哪些区域不再那么。
Alternativly你可以在这里发布的存储过程,为人们提出的优化。
Answer 7:
一开始它听起来并不像SQL是怎么回事基础上,采用了多项临时表来执行反正太清楚(可以在内存中保存,或者保存到tempdb中 - 无论SQL Server的决定是最好的),和使用游标。
我的建议是,看看你可以重写存储过程作为一个基于集合的查询,而不是光标的方法,这将提供更好的性能,并且更容易调整和优化了不少。 很显然,我不知道你的存储过程究竟是干什么的,并进行指示,以多么容易/可行的,这是给你的。
至于为何SP正在比查询更长 - 很难说。 有没有在系统上相同的负载,当您尝试每一种方法? 如果您运行查询本身时,有一个轻负载时,它会在你重负载时运行SP不是更好。
同时,为了确保查询确实是比SP更快,你需要排除的数据/执行计划的缓存,这使得查询的后续运行速度更快。 您可以清除缓存使用出来:
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
但仅仅做到这一点的一个开发/测试数据库服务器上,而不是生产。 然后运行查询,记录的统计数据(例如,从分析器)。 再次清除缓存。 运行SP和比较的统计数据。
Answer 8:
1)当您运行首次查询可能需要更多的时间。 还有一点是,如果你使用任何corellated子查询,如果你硬编码的值将仅一次被执行。 当你不硬编码,并通过程序运行它,如果你想导出从输入值的值,那么它可能需要更多的时间。
2)在极少数情况下,它可能是由于网络流量,同时,我们也不会在查询执行时间相同的输入数据的一致性。
Answer 9:
在这里我们不得不创造一些临时表,然后操纵他们必须计算基于规则的一些价值观,终于在第三个表中插入计算值我也遇到了问题。 这一切,如果放在一个SP正在采取约20-25分钟。 因此,要进一步优化它,我们打破了SP进入3个不同的SP的,现在所用的总时间约为6-8分钟。 只要确定参与了整个过程,以及如何打破他们在不同的SP的步骤。 当然使用这种方法通过将整个过程拍摄总时间将减少。
Answer 10:
我建议这个问题是关系到临时表(#前缀)的类型。 该临时表适用于该数据库会话的数据。 当你通过你的应用程序运行的临时表被删除并重新创建。
当SSMS运行它使会话数据和更新表,而不是创建它的你可能会发现。 希望帮助:)