2

我有一个呈现从存储过程返回的数据的报告。使用分析器,我可以从报告服务中捕获对存储过程的调用。

报告失败,说明报告超时,但我可以从 SSMS 执行存储过程,它会在五到六秒内返回数据。

请注意,在示例测试运行中,只有两行返回到报告中以进行渲染,尽管在存储过程中它可能已经处理了数千甚至数百万条记录,以便整理传递回报告服务的结果。

我知道存储过程可以进行更多优化,但我不明白为什么当从 SSMS 执行似乎只需要几秒钟时 SSRS 会超时。

另一个问题也浮出水面。如果我重新创建存储过程,报表将再次完美呈现。这很好,除非在短时间内报告再次开始超时。

超时的返回似乎与添加到报告运行的主表中的新数据有关。在我正在测试的示例中,仅插入 100 条新记录就足以搞砸报告。

我更正确地想象它不是根本原因的报告。从 SSRS 执行时,导致超时的是存储过程。

一旦再次超时,我目前最好的解决方法是重新创建存储过程。这似乎不是一个理想的解决方案。

该问题似乎也只发生在我们的生产环境中。我们的测试和开发平台似乎没有出现同样的问题。尽管开发和测试的记录量与生产量不同。

4

4 回答 4

2

正如您所描述的,问题似乎来自存储过程中某些部分的执行计划的变化。查看使用的表保留了哪些统计信息以及添加新行如何影响它们。

如果您在列范围的末尾添加很多行(考虑添加自动编号或时间戳),该列的直方图将很快过时。您可以通过执行 UPDATE STATISTICS 语句从 T-SQL 强制立即更新。

于 2008-10-25T22:10:37.877 回答
2

我也遇到过这个问题,即 SPROC 需要几秒钟才能运行,但 SSRS 只是超时。

根据我自己的经验,我发现有几种不同的方法可以解决这个问题。

  1. 是参数嗅探!当您的存储过程从 SSRS 执行时,它会“嗅出”您的参数以查看您的 SPROC 是如何使用它们的。SQL Server 随后将根据其发现生成一个执行计划。这在您第一次执行 SPROC 时很好,但您不希望它在每次运行报表时都这样做。因此,我在 SPROC 的顶部声明了一组新变量,它们仅存储在查询中传递的参数并在整个查询中使用这些新参数。

例子:

CREATE PROCEDURE [dbo].[usp_REPORT_ITD001]
@StartDate DATETIME,
@EndDate DATETIME,
@ReportTab INT
AS

-- Deter parameter sniffing
DECLARE @snf_StartDate DATETIME = @StartDate
DECLARE @snf_EndDate DATETIME = @EndDate
DECLARE @snf_ReportTab INT = @ReportTab

...这意味着当您的 SPORC 由 SSRS 执行时,它只会查看查询中的前几行以获取传递的参数,而不是整个查询。这大大减少了 SSRS 中的执行时间。

  1. 如果您的 SPROC 有很多被声明为变量 ( DECLARE @MyTable AS TABLE) 的临时表,那么在生成报告时这些临时表在服务器上(就内存而言)是非常密集的。通过使用散列临时表 ( SELECT MyCol1, MyCol2 INTO #MyTable),SQL Server 会将您的临时表存储在服务器上的 TempDB 中,而不是系统内存中,从而减少报告生成的密集度。
于 2011-01-13T11:05:47.340 回答
1

有时在存储过程的 CREATE 语句中添加 WITH RECOMPILE 选项会有所帮助。这在过程探索的记录数量以原始执行计划不是最优的方式发生变化的情况下是有效的。

于 2008-10-28T13:06:14.027 回答
0

基本上到目前为止,我所做的只是进一步优化存储过程,它似乎至少暂时解决了这个问题。

我仍然想知道从 SSMS 和 SSRS 调用 sproc 之间有什么区别。

于 2008-10-28T19:24:29.210 回答