SSRSに基づくストアドプロシージャが数秒以内に結果を返すときに、SSRSがタイムアウトするのはなぜですか?

StackOverflow https://stackoverflow.com/questions/237069

質問

ストアドプロシージャから返されたデータを表示するレポートがあります。プロファイラーを使用すると、レポートサービスからストアドプロシージャの呼び出しをキャッチできます。

レポートがタイムアウトになったという報告に失敗しましたが、SSMSからストアドプロシージャを実行でき、5〜6秒でデータが返されます。

注:サンプルテストの実行では、レポートに返される結果を照合するためにストアドプロシージャ内で数千または数百万のレコードを処理している可能性がありますが、レンダリングのために2行のみがレポートに返されます。

ストアドプロシージャをさらに最適化できることは知っていますが、SSMSから実行するのに数秒しかかからないように見えるのにSSRSがタイムアウトする理由はわかりません。

また、別の問題が表面化しました。ストアドプロシージャを再作成すると、レポートは再び完全に正常にレンダリングされ始めます。しばらくすると、レポートは再びタイムアウトになりますが、それ以外は問題ありません。

タイムアウトの戻り値は、レポートが実行されているメインテーブルに追加される新しいデータに関連しているようです。私がテストしていた例では、100件の新しいレコードを挿入するだけで、レポートが台無しになりました。

根本的な原因であるレポートではなく、より正確に想像します。 SSRSから実行されたときにタイムアウトを引き起こしているのは、ストアドプロシージャです。

もう一度タイムアウトになると、これまでのところ、ストアドプロシージャを再作成するのが最善の解決策です。これは理想的な解決策ではないようです。

この問題は、実稼働環境でのみ発生しているようです。テストおよび開発プラットフォームでは、同じ問題が発生していないようです。 devとtestには本番と同じ量のレコードがありません。

役に立ちましたか?

解決

問題は、あなたが説明したように、ストアドプロシージャの一部の実行計画のバリエーションに起因するようです。使用されているテーブルで保持されている統計と、新しい行の追加がそれらに与える影響を確認します。

  

で多くの行を追加する場合   列の範囲の終わり(考える   オートナンバーの追加について、または   タイムスタンプ)、そのヒストグラム   列は急速に古くなっています。   すぐに強制的に更新できます   UPDATEの実行によるT-SQL   STATISTICSステートメント。

他のヒント

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. 変数として宣言されている多くの一時テーブル( DECLARE @MyTable AS TABLE )がSPROCにある場合、これらはレポートを生成するときにサーバー上で(メモリの点で)かなり集中します。代わりにハッシュ一時テーブル( SELECT MyCol1、MyCol2 INTO #MyTable )を使用することにより、SQL Serverは一時テーブルをシステムメモリではなくサーバー上のTempDBに保存し、レポート生成の負荷を軽減します。

WITH RECOMPILEオプションをストアドプロシージャのCREATEステートメントに追加するのが役立つ場合があります。 これは、元の実行計画が最適ではない方法でプロシージャによって探索されるレコードの数が変化する状況で効果的です。

基本的にこれまでにやったことは、sprocをもう少し最適化することだけで、少なくとも一時的に問題を解決するようです。

SSMSからsprocを呼び出す場合とSSRSから呼び出す場合の違いは何ですか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top