今日、「この計表を期間1年で出したのはまずかったですかねぇ」と言われて、行ってみると.NETのエラーが表示されていた。よく見ると、CLRがメモリ不足により異常終了したとのメッセージ。
このCLRは、IEに対してExcelに吐き出すVBScriptを生成して返すものだが、まさかこんなメッセージが出るとは思わなかった。
一体どれくらいのデータを返そうとしたのか、対象のストアドを実行してみると、50000件×40列。そう、この計表は明細データを出力するので、1年くらいの期間で取ると、これぐらいになってしまう。盲点だった。
CLRにしたということは、まとめて返す文字列はいったん全部メモリにため込まれてしまうということらしい。
64ビットとはいえ、WindowsもSQL ServerもStandardでメモリは4GBしか積まれていない。
SQL Serverのログを見てみると、
「A significant part of sql server process memory has been paged out. This may result in a performance degradation.」というメッセージの次に、CLRが叩き落されていた。このメッセージはメモリ使用量が45%を超えると出るらしい。メモリコントロールのソリューションを取るほどそもそもメモリがない。
実際、5万件の入力チェックリストを出力することはあり得ないのだが、それにしてもこのまま放置しておくのは危険なので、あまり大量なデータを返さないように制約を掛けるしかなさそうだ。
昔、JavaでCSVを吐くという処理を書いたときに、StringBufferに20MBもため込んだら、「Out Of Memory」を返されたのを思い出した。環境次第とはいえ、今回のCLRもStringBuilderにため込んでいたわけだから、同じような事象のわけで。。うーん。