Oh man, that did it. The document library went from rendering in 6+ seconds to rendering in less than 1 second.
[From Improving Alfresco Share performance by using getChildren | ecmarchitect.com]
Jeff Potts氏のBlog、ecmarchitect.comに多数のサイトを作成した場合におけるAlfresco Shareの文書ライブラリ(とデータリスト)のパフォーマンス低下の問題とその解決策についての記事があがっていました。
問題となった環境には1000を超えるサイトがあり、サイト1つあたりの情報量は特段大きくはない、という状況だったようです。その中で、フォルダツリーは素早く表示されるが、個別のファイルの表示には時間がかかるという現象が見られた。
彼は当初、スクリプトからAlfrescoのノードを操作使用とした場合あらゆる情報はLucene経由で提供される、と勘違いをしていたそうです。LuceneクエリとDBクエリの使い分けはロードマップ上にはあってもまだ実装されていないだろう、と。(全文検索だけでなく属性値の検索にもLuceneを使っているというのは周知の事実であり、この点は我々にとっても常に混乱の元になっています。) そのため、何故フォルダツリーの表示だけは素早く表示されるのか、という点を誤解したままパフォーマンス改善にあたることになってしまいました。
Google Docsのコードやチェックアウト機能、アスペクトのチェック、フィルタ機能、と様々な機能を取り外してみたそうです。それぞれに僅かな改善効果があったそうですが、とても十分であるとはいえない状況だったそうです。
次に、ログを仕込んで実行時に時間がかかっている部分の特定にかかります。当然、クエリの部分が該当するわけですが、ノードに対して子ノードを問い合わせる処理(getChildrenの呼びだし)はPARENT節を含むLuceneクエリよりも有意に早いということが判明しました。
Alfresco Shareの文書ライブラリはYUIのテーブルを使って選択されているフォルダ内の文書リストを表示します。このテーブルはリポジトリに配置されているリスト情報を詰め込んだJSONを返すWebスクリプトにバインドされています。標準ではこのWebスクリプトはUI上で選択されてフィルタについての情報をgetFilterParamsを経由して取得した上でLuceneクエリを生成します。
当該サイトの場合はフィルタ機能の必要性が薄かったため、このステップを省略し、選択されたフォルダの情報を使ってgetChildrenを直接呼び出して高速化を図ったところ処理時間が6分の1以下になったということです。(ALLフィルタ選択時には、getChildrenバージョンのWebスクリプトを利用する、という仕組みでフィルタ機能を外したわけではないようですが)
このあたりのノウハウはバージョンが変わるとまた違ってきてしまうと思いますが、ご参考まで。
(文責 Ishii Akinori IT-Coordinator)