Known Issue: Reporting Services への初回アクセス時に、レポート表示に時間がかかる。

小林 真治
SQL Developer Support Escalation Engineer

今回は、同一レポート/データを利用した際のレポートの表示パフォーマンスが悪化する現象における、 Reporting Services の既定の動作に起因したパフォーマンス悪化の要因として考えられること、並びに対処策について解説します。

同一レポート/データを利用した際にレポートの表示パフォーマンスが通常より遅い場合、一般的には、該当レポートを表示した際の同時実行性に起因したサーバーリソースの枯渇が要因として考えられます。
しかしながら、ある特定の時間において 1回だけ表示パフォーマンスが遅い場合や、 Reporting Services サービスを再起動した直後に表示パフォーマンスが遅いなどの現象が発生している場合、下記の動作に起因している可能性があります。

Reporting Services は、下記イベントが発生した場合、イベント発生後に最初にリクエストされたレポートを表示するタイミングで、自身が動作するために必要なモジュールを読み込みます。
このため、これらのイベントの直後、レポートを表示するまでに時間がかかることがあります。

- Reporting Services のサービス再起動後

- Reporting Services の定期的なリサイクル処理発生後 (既定で 12 時間毎)

- 他、レポートサーバー、および、ASP.NET の構成変更やメモリ不足とメモリ割り当て失敗時などのタイミング

尚、一番初めにリクエストされたレポートを表示するタイミングで Reporting Services は、下記を実施しています。 

- Reporting Services プロセス内 Web サービス用アプリケーションドメインの生成

- Reporting Services プロセス稼働に必要なモジュールの読み込み

このため、それぞれのイベント発生後の最初のレポート表示は、通常より遅延する可能性があり、残念ながら、この動作を Reporting Services のパラメータや構成などで制御することはできません。
しかしながら、 上記動作をユーザーによるレポート表示要求よりも先に実施させることで、最初のレポート表示時におけるパフォーマンス悪化を緩和することが可能です。

一例とはなりますが、バッチでのレポートサーバーへのアクセスする方法について記載しました。
下記スクリプトを、「ReportServerAccess.vbs」等の名称で保存し、「cscript ReportServerAccess.vbs」と実行することで、ユーザーが最初のレポート表示遅延に遭遇する可能性を抑制できます。

----ここから------

Option Explicit

' 該当のレポートサーバーのURL を指定

Const cURL = "https://localhost/ReportServer/"

 Dim oIE, stUrl

 WScript.Echo("Set Variables")

stUrl = cURL

 ' IE を起動

WScript.Echo("Create IE Object.")

Set oIE = CreateObject("InternetExplorer.Application")

 WScript.Echo("Make IE visible.")

oIE.Visible = true

 WScript.Echo("Change IE size.")

oIE.width = 800

oIE.height = 600

 ' 該当ページに移動

WScript.Echo("Go to URL = " & stUrl)

oIE.Navigate stUrl

 ' IE のロードを待つ

WScript.Echo("Waiting for IE.")

Call WaitIE

 ' 終了前に少し待つ

WScript.Sleep(10000)

 ' 終了

oIE.Quit()

Set oIE = nothing

 ' ============================================================================

' WaitIE  (IE のロードを待つ)

' ============================================================================

Sub WaitIE

Do While oIE.busy

WScript.Echo("Waiting for loading page...")

WScript.Sleep(1000)

Loop

 Do While oIE.Document.readyState <> "complete"

WScript.Echo("Waiting for rendering page...")

WScript.Sleep(1000)

Loop

End Sub

 ----ここまで------

 ※ 留意事項
本サンプルは、本ブログの説明の為のものとなり、弊社にてその動作を保証するものではございません。
ご使用の際には、ご利用のシステムに合わせて修正して頂き、十分なテストを実施して頂きます様お願い致します。 
サンプル内で使用しております API などの詳細な情報に関しては、MSDN 、PlatformSDK などをご参照ください。