
Query Result Cache - 日本エクセム株式会社 Oracle 技術情報
SQLチューニングのためには、そのSQLがどのように動いていて、データベースにどのように影響しているのか、を把握する必要があります。『MaxGauge』があれば簡単に状況が把握でき、適切なSQLチューニングができるようになります。
『MaxGauge』の資料はこちらから。
基本情報
繰り返されるqueryの応答速度を改善するためにOracle 11gでは、メモリ領域にresult cacheを使用する機能を導入しました。Result Cacheは、shared poolのResult Cache Memoryと呼ばれる領域にSQLとPL/SQL funtionの結果を格納する機能です。
特定のqueryが繰り返し実行されるときに、この結果をキャッシュして、その次からはそのqueryを再実行するのではなく、キャッシュメモリに格納された結果の値をそのまま使用するようになります。この場合、db負荷だけでなく、応答速度の大幅な向上を期待することがことができます。
このresult cacheは、すべてのセッションのために共有されており、この保存された結果は、queryがアクセスするobjectが変更されると破棄されます。このresult cacheそれ自体はインスタンスごとに、それぞれ保存され、その使用局面においてはDatabase全体をカバーします。
この機能を使用しない場合はRESULT_CACHE_MAX_SIZEパラメータを0にセットしてinstanceを再起動する必要があります。 RACの場合も同様です。
Result Cacheに関連するパラメータ
NAME | VALUE | 説明 |
result_cache_mode | MANUAL |
|
_result_cache_auto_size_threshold | 100 | result cache auto max sizeを設定 |
_result_cache_auto_time_threshold | 1000 | result cache auto timeしきい値 |
_result_cache_auto_execution_threshold | 1 | result cache auto executionしきい値 |
result_cache_max_size | 1048576 | キャッシュによって使用されるメモリの最大量 0の場合は未使用 |
result_cache_max_result | 5 | キャッシュサイズのパーセンテージとしての最大結果サイズ |
result_cache_remote_expiration | 0 | リモートオブジェクトを使用するすべての結果の最大存続時間(分) |
_result_cache_block_size | 1024 | Result Cacheブロックサイズ |
_result_cache_timeout | 60 | セッションが結果を待つ最大時間(秒) |
_result_cache_auto_time_distance | 300 | Result Cache自動時間間隔 |
client_result_cache_size | 0 | クライアントResult Cacheの最大サイズ(Byte)0の場合は未使用 |
client_result_cache_lag | 3000 | クライアントのResult Cacheの最大遅延時間(ミリ秒単位) |
_client_result_cache_bypass | FALSE | クライアントのResult Cacheをバイパスするかどうか |
_xsolapi_sql_result_set_cache_size | 32 | OLAP API Result Cacheサイズ |
Result Cacheに関連するDictionary View
Result Cacheを制御するPackage
Oracleは、result cacheを制御するためにDBMS_RESULT_CACHEというパッケージを提供します。このパッケージのサブプログラムは、次のとおりです。
Status Funtionの値は、以下のようになっており、これは奇妙に見えます。
STATUS_CLSD | Cacheは、使用できません。 |
STATUS_OPEN | Cacheは、使用できます。 |
STATUS_SYNC | Cacheは、使用できますが、RACノードと同期しています。 |
しかし、実際は以下の通りです。
以下はDBMS_RESULT_CACHE.MEMORY_REPORTを実行した結果です。
SQL Query result Cacheの使用
SQL query result Cacheの使用は、RESULT_CACHE_MODEパラメータによって制御が可能です。このパラメータは、MANUALとFORCEという値を持つことができます。
MANUALの場合、Result Cacheを使用するには、特定のSQLブロックにresult_cacheヒントを使用しなければなりません。FORCEの場合は、すべての結果を保存するためno_result_cacheというヒントを使用して、これを回避することができます。最も最近使用されたアルゴリズムは、cache resultをage outされるようにするため、もしresultが使用可能なメモリ容量よりも大きい場合は、キャッシュがありません。
MANUALモードでResult Cacheを使用するには、次のように使用すれば良いのです。
この場合、以下のようなプランが表示されます。
RESULT CACHEというオペレーションが表示されます。RESULT CACHEオペレーションは、一度result cache memoryを見つけ、もしこの結果がcacheにあればすぐに結果の値を取得し、それ以外の場合、これを実行して、結果の値をresult cache memoryに保存します。
いくつかの実験をしてみましょう。
Javaのアプリケーションquery_result_cache.classを通じてCacheを使用する場合と使用しない場合の性能を比較してみます。このアプリケーションで使用したSQLとPlanは、以下の通りです。
これを実行すると以下のような違いが現れました。
Stat | No Cache | Cache |
table scan rows gotten | 140072 | 72 |
session logical reads | 90052 | 20052 |
table scan blocks gotten | 50003 | 3 |
table fetch by rowid | 40016 | 40016 |
execute count | 10009 | 10009 |
user calls | 10007 | 10007 |
CPU used by this session | 483 | 85 |
Elapsed_Time | 10.157 | 5.313 |
指標から見ると、Full Scanの仕事量に格段に差が出て、最終的にLogical Readや実行時間に大きな違いを示すことがわかります。Planから見れば、Full Scanが使用されている部分は、in line viewであるため、Result Cacheを使用すると、かなりの部分の性能を向上させることができるということを証明しています。
Client Query Result Cacheの使用
今まではShared Poolを利用したQuery Result Cacheを調べて来ました。ここではClientのメモリ領域、特にOCIのメモリ空間を使用したQuery Result Cacheも使用が可能です。これは、使用する方法は同じですが、どこのCacheがされているかの違いが発生します。
ところが、Clientにcacheとして、そのセッションやプロセスにのみ適用されるメカニズムではないのです。この機能を使用すると、優先的にShared memoryにcacheされてOCIのこれに対するコピーを再Cacheすることになります。したがって、database領域にわたってResult Cacheが行われるようになるのです。この機能を使用すると、latchの獲得の試みが減少するなどのShared memoryの負荷を軽減という利点を享受することができるようになります。
OCIのResult Cacheは、継続して使用をすると維持しますが、そうでなければclient_result_cache_lagに設定された時間ごとにShared Memoryと同期を取ることになります。
この機能を使用するには、前述したように、CLIENT_RESULT_CACHE_SIZEの値を付与すればよいのです。
SQL Query Result Cacheの制約
次の場合には、SQL Query Result Cacheの使用に制約を受けることになります。
上記のように結果の値が変更される余地がある場合は、使用が不可能か、または制約を受けるということを思い出してください。
SQLチューニングのためには、そのSQLがどのように動いていて、データベースにどのように影響しているのか、を把握する必要があります。『MaxGauge』があれば簡単に状況が把握でき、適切なSQLチューニングができるようになります。
『MaxGauge』の資料はこちらから。
