SQL とキャッシング (DB2/400)

こちらの記事の修正になります。

動的 SQL のキャッシング (アクセス・プラン/ODP)

動的 SQL のキャッシュの歴史

SQL の実行時には構文解析/最適化/実行という三つの過程があります。

発行された SQL について、まず構文が正しいかどうかが検査され、アクセスされるテーブルについてサイズや行数や中のデータの偏りなどを元に最適なアクセス方法を決定し、それに基づいて実行される、という三段階です。
DB2/400 では、このうち、最適なアクセス方法が「アクセス・プラン」と呼ばれるもので、実行する時にジョブが使用するものが「オープン・データ・パス」というものになります。

同じ SQL が発行された場合、同じ SQL であれば同じアクセス・プランが有効なので再作成するのはシステム資源の無駄なわけですし、同じジョブで実行されたような場合にオープン・データ・パスもあらかじめ開かれていれば余計な負荷がかからないわけです。

オープン・データ・パスについてはジョブの構造の一部であるため、同じジョブで同じ SQL が実行された時に以前実行されたものが残っていて使用できるといいね、というかんじですが、アクセス・プランについてはジョブをまたがって共有できるようなものなので、何らかの共有する仕組みがないともったいないわけです。

もともと作成されたアクセス・プランは、静的 SQL の場合はプログラム自身に、動的 SQL の場合はジョブのワーキングメモリにのみ格納される、というのが最初の仕様でした。
それではあまりに動的 SQL の場合にはパフォーマンスが悪くなりすぎる、ということで、拡張動的 SQL というものが新しく作られ、SQL パッケージに保管されて再利用できるようになりました。

ただし、拡張動的 SQL を使うのにはそれなりのお作法が必要なため、それほど普及せず、動的 SQL について IBM が目論んだ「拡張動的 SQL を使ってください。以上終わり」というわけにはいきませんでした。
結局、 動的 SQL についてはシステムワイド・ステートメント・キャッシュ (SWSC) というものがサポートされるようになっています。

キャッシュのサーチ順

動的 SQL はまずジョブ・キャッシュに SQL 文 (Statement Text) と SQL 文名 (Statement Name) をサーチに行きます。このジョブ・キャッシュへのサーチが、「ジョブのワーキングメモリにのみ格納される、というのが最初の仕様」の最初の仕様だったわけです。

両方ヒットすればアクセス・プランODP も再利用できるのでパフォーマンスは一番いいのですが、これは JDBC などから飛んできた動的 SQL がまったく同じ QZDASOINIT ジョブに当ったケースなので、アプリケーション実行環境によってはけっこうなラッキーケースになってしまうかもしれません。

ジョブ・キャッシュといっても、最初からキャッシュに入るわけではありません。

ジョブ・キャッシュにヒットしなかった場合、先ほど触れたシステムワイド・ステートメント・キャッシュ (SWSC) というものにアクセス・プランを探しに行きます。
ここでヒットしなかった場合、アクセス・プランは新規にまたは再作成されることになります。

作成されたアクセス・プランはそこでシステムワイド・ステートメント・キャッシュにキャッシュされると同時にジョブ・キャッシュにもそのポインタがキャッシュされる、という仕組みになっています。
飛んできた動的 SQL が同じジョブに運良く当ればジョブ・キャッシュにヒットしてアクセス・プランと ODP が再利用でき、別のジョブに当ったとしてもジョブ・キャッシュの次にサーチされたシステムワイド・ステートメント・キャッシュにヒットしてアクセス・プランの再利用ができるというわけです。

もともと動的 SQL の場合は、ジョブのワーキング・メモリにのみアクセス・プランがキャッシュ (= ジョブ・キャッシュ) されてしまうため、別のジョブからは ODP などと同様に再利用することはできなかったわけです。これを改善するためにシステムワイド・ステートメント・キャッシュが作られた、ということになります。
ODP はジョブ構造の一部なのでさすがに別のジョブから再利用することはできません。

SQL 文 (Statement Text) のみがヒットした場合は、アクセス・プランのみが再利用されます。

SQL のタイプとキャッシュ、およぶエンジンによる違い

この動的 SQL の話と以前の記事をあわせて考えると、DB2/400 では実行される SQL のタイプ毎に以下のようにアクセス・プランがキャッシュされる、ということになります。

SQE の場合、やはりこちらにまとめた記事にあるように、アクセス・プランはまとめてプラン・キャッシュというものにキャッシュされるようになっているのですが、新たに直接プラン・キャッシュにアクセスするようになるわけではありません。
各 SQL のタイプとキャッシュとのインターフェイス自体は変わらずその各キャッシュにアクセスに行くのですが、実は実体がプラン・キャッシュに存在する、という形になっています。

[Top Pageに戻る]

Ads by TOK2