リージョン属性にサーバー・キャッシュというのがあるけど、これを有効にしたら表示が速くなるの?と聞かれたので、調べてみました。この機能を使った経験はありません。
ページ属性にも同様にサーバー・キャッシュがあります。
ページ属性のサーバー・キャッシュについては、マニュアルに説明を見つけることができませんでした。本来であれば、7.4 ページ属性の管理で説明されているはずの属性です。
最近のWebページは、すべてのHTMLをサーバー側で生成するということはなく、クライアント側のJavaScriptによる画面の書き換えも一般的です。このサーバー・キャッシュの機能は、JavaScriptの使用がまだ一般的ではなかった頃(そしてサーバー側のリソースが今より弱かった頃)は有効だった、古の機能と言えます。
これより、リージョン属性のサーバー・キャッシュを中心に、その動作を確認してみます。
動作確認に使用するアプリケーションは、以下の手順で作成します。
アプリケーション作成ウィザードを起動します。アプリケーションの名前はServer Cacheとします。
デフォルトで作成されているホーム・ページを削除し、表EMPをソースとしたフォーム付きのクラシック・レポートと、同様に表EMPをソースとした(フォームを付けない)クラシック・レポートのページを追加します。
以上でアプリケーションを作成します。
作成したアプリケーションのホーム・ページが以下になるよう、Deptnoのページ・アイテム、レポートをリフレッシュするボタン、キャッシュされたリージョンのデータをパージするボタンを作成します。
識別の名前はP1_DEPTNO、タイプはテキスト・フィールドを選択します。ラベルはDeptnoとし、設定の[Enter]を押すと送信をオンにします。
静的IDのemployeesは、キャッシュされたリージョンのデータをパージする際に必要な、リージョンIDを取得するために使用します。
画面右のアプリケーション・キャッシュを開きます。
ボタンREFRESHを作成し、ボタンをクリックするとレポートをリフレッシュする動的アクションを作成します。
ラベルはRefresh、外観のテンプレート・オプションのWidthにStretchを指定しています。動作のアクションは動的アクションで定義を選択します。
動的アクションの名前はレポートのリフレッシュ、タイミングのイベントはボタンのデフォルトであるクリックです。
TRUEアクションとしてリフレッシュを選択します。影響を受ける要素の選択タイプとしてリージョンを選び、リージョンとしてクラシック・レポートであるEmployeesを選択します。
以上でボタンREFRESHを押すと、クラシック・レポートが更新されるようになりました。
キャッシュされたリージョンのデータをパージするボタンPURGE_CACHEを作成します。
ラベルはPurge Cache、レイアウトの新規行の開始をオフにして、ボタンREFRESHの右隣に配置します。外観のテンプレート・オプションのWidthを、ボタンREFRESHと同様にStretchに変更します。動作のアクションはデフォルトのページの送信から変更しません。
このボタンPURGE_CACHEをクリックしたときに実行するプロセスを作成します。
左ペインでプロセス・ビューを開き、プロセスを新規作成します。
識別の名前はキャッシュのパージ、タイプとしてコードを実行を選択します。ソースのPL/SQLコードとして以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_region_id apex_application_page_regions.region_id%type; | |
begin | |
select region_id into l_region_id | |
from apex_application_page_regions | |
where application_id = :APP_ID | |
and page_id = :APP_PAGE_ID | |
and static_id = 'employees'; | |
apex_region.purge_cache( | |
p_page_id => :APP_PAGE_ID | |
,p_region_id => l_region_id | |
); | |
end; |
サーバー側の条件のボタン押下時にPURGE_CACHEを設定します。
以上でサーバー・キャッシュの動作を確認するアプリケーションは完成です。
キャッシュされているデータの確認は、ワークスペースの管理から行います。
ワークスペースの管理からサービスの管理を開きます。
リージョン単位でキャッシュされたデータを確認するには、キャッシュされたリージョン別リージョンのパージを開きます。
今の所何もキャッシュされていないので、何も表示されません。
リージョンEmployeesのサーバー・キャッシュのキャッシュを有効にします。有効の場合、すべてのアクセスで同じキャッシュを使用します。ユーザー別またはセッション別にキャッシュを持つことも可能です。
それ以外は特に設定せず、効果を確認してみます。
最初は部門番号が設定されていないため、以下のように一行も従業員が表示されません。
アプリケーション・キャッシュの画面から確認できます。
レポートの遅延ロードがオンの場合も、動的アクションによるリフレッシュと同様にクライアント側で描画されるため、サーバー・キャッシュの影響を受けません。
Deptnoに10を入力し、Enterを入力します。P1_DEPTNOとして10が送信され、レポートが再表示されますが、データが見つかりませんと表示されます。
これはキャッシュにヒットしているためで、この時点ではDeptnoに何を入力しても、結果はデータが見つかりませんとなります。
しかし、ボタンRefreshをクリックすると、Deptno = 10(ACCOUNTING)に所属する従業員が一覧されます。これはクライアント側でレポートの描画を行なっているためです。
クライアント側で描画されたレポートはサーバー側でキャッシュされません。Deptnoに20を入力しEnterを押すと、キャッシュにヒットするためデータが見つかりませんと表示されます。
Deptnoに30を入力しEnterを押します。遅延ロードがオンの場合は、部門がSALESの従業員が一覧されます。
Deptnoに20を入力し、Purge Cacheをクリックします。
今までキャッシュされていたリージョンのデータがパージされます。その後にDEPTNO = 20の条件でレポートが表示されます。このレポートは新たにキャッシュされます。(そのため、Deptnoに10や30を入れてEnterを押しても、部門RESEARCHの一覧が表示されます。)
従業員ADAMSの編集フォームを開き、Salaryを1100から2200に変更します。
変更の適用をクリックします。
フォームが閉じると、ADAMSのSalaryが2200に更新されています。
しかし、DeptnoでEnterを押してレポートを更新すると、ADAMSの給与は1100に戻ります。フォームを閉じたときにリージョンがリフレッシュ(つまり、クライアント側で描画)されるためです。データベースで保持されているSalaryは2200に更新されています。
その点を考慮すると、クラシック・レポート(遅延ロードはオフ、リフレッシュが発生する処理は含めない)および動的コンテンツ(同様に遅延ロードはオフ、リフレッシュが発生する処理は含めない)であれば、サーバー・キャッシュを活用できそうです。
今回のようなケースではサーバー・キャッシュのアイテムに依存にP1_DEPTNOを設定します。
リージョンがキャッシュされるにあたり、指定したページ・アイテムの値が紐付けされます。
アイテムに依存にP1_DEPTNOを設定すると、Deptnoに10、20、30と値を入れてEnterを押したとき、指定した部門の従業員が一覧されるようになります。
検索条件を変えずにレポートの再表示が行われるケースが多ければ、サーバー・キャッシュを設定することによりサーバーの負荷を軽減できる可能性があります。
キャッシュが使用される条件を設定することもできます。
タイプとしてアイテムはコロンで区切られたリストに含まれるを選択し、アイテムにP1_DEPTNO、リストとして10:20を指定します。
サーバー・キャッシュが有効なのはDeptnoが10と20のときに限る、という設定になります。
Deptnoに10を入力しボタンPurge Cacheをクリックして、Deptnoが10のレポートがキャッシュされた状態にします。
MILLERのSalaryはレポート上も2600に更新されますが、これはリージョンがリフレッシュされたため(クライアント側で再描画が行われたため)です。
Deptnoの10および20はキャッシュの対象ですが、30と40は対象から外しています。Deptnoを30にして、同様の操作を行ってみます。
Deptnoに30を入力し、ボタンPurge Cacheをクリックします。
今までの手順でクラシック・レポートより更新フォームを開いていますが、この操作ができるのは同じセッションでキャッシュされたHTMLに限定されます。異なるセッションよりキャッシュされたHTMLの場合、編集フォームを開こうとするとチェックサムに関するエラーが発生します。
編集リンクに含まれているcs=で与えられているチェックサムの値は、リージョンをキャッシュしたセッションで計算されています。検証に使うチェックサムはキャッシュを参照しているセッションで計算されるので、セッションが異なるためチェックサムが一致しません。
以上のように、サーバー・キャッシュが活用できる場面はかなり限定されています。とはいえ、活用できる条件に合致さえすれば、間違いなくサーバーの負荷を減らすことができるでしょう。
ページのサーバー・キャッシュは、さらに活用できる場面は限定されています。
ページ上で対話的なオペレーションはなく、データベースのデータを参照してページを生成しているが、内容の更新が発生しない場合は、ページのサーバー・キャッシュを活用できそうです。
上記のように表EMPの一覧を表示しているような状態で、表EMPに変更があったときにAPEX_PAGE.PURGE_CACHEを呼び出してキャッシュを削除する、といった運用をすると、このページのHTMLを生成する負荷を削減できます。
キャッシュされたページについては、アプリケーション・キャッシュのキャッシュされたページ別ページのパージより確認できます。
キャッシュ・モード = 有効を条件として、ページを一覧します。
サーバー・キャッシュについての説明は以上になります。
今回の説明に使用したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/server-cache.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完