新・ソートに関する検証 その2
<新・ソートに関する検証 その2>
ペンネーム グリーンペペ
今回も検証生活~基礎編~です。
pga_aggregate_targetはインスタンス内で使用可能なPGAの総量を指定します。
では指定したサイズを1プロセスが消費し尽くすことができるのでしょうか?
それともリミッターのようなものはあるのでしょうか?
pga_aggregate_targetの値を動的に変更してみて、1プロセスがソート処理に
使用するメモリ領域の上限を検証してみます。
□環境
OS:Red Hat Linux release 7.1
Oracle:9.2.0.1
□自動PGA管理に設定
SQL> alter system set pga_aggregate_target=10M; システムが変更されました。 SQL> alter system set workarea_size_policy=auto; システムが変更されました。
□ソート処理を実行:pga_aggregate_target = 10M
SQL> set timing on SQL> select distinct * from code where rownum<1000000; 経過: 00:01:45.43
▽sql作業領域の情報を見る
SQL> select sql_text,operation_type,policy,last_memory_used/1024/1024,last_execution, last_tempseg_size from v$sql l,v$sql_workarea a where l.hash_value=a.hash_value and sql_text='select distinct * from code where rownum<1000000'; SQL_TEXT OPERATION_TYPE ------------------------------------------------ ---------------- select distinct * from code where rownum<1000000 GROUP BY (SORT) POLICY LAST_MEMORY_USED/1024/1024 LAST_EXECUTION LAST_TEMPSEG_SIZE ------ ---------------------------- -------------- ----------------- AUTO .5 61 PASSES 26214400
LAST_MEMORY_USED列に注目してください。
pga_aggregate_target=10Mと設定していますが、10M全てを1プロセスにて消費
してしまうのではないようです。
以下、徐々にpga_aggregate_targetの値を大きくしていきます。
□pga_aggregate_target = 20Mに変更
SQL> alter system set pga_aggregate_target=20M; システムが変更されました。 SQL> select distinct * from code where rownum<1000000; 経過: 00:01:04.61 SQL> select sql_text,operation_type,policy,last_memory_used/1024/1024,last_execution, last_tempseg_size from v$sql l,v$sql_workarea a where l.hash_value=a.hash_value and sql_text='select distinct * from code where rownum<1000000'; SQL_TEXT OPERATION_TYPE ------------------------------------------------ ---------------- select distinct * from code where rownum<1000000 GROUP BY (SORT) POLICY LAST_MEMORY_USED/1024/1024 LAST_EXECUTION LAST_TEMPSEG_SIZE ------ ---------------------------- -------------- ----------------- AUTO 1.09570313 4 PASSES 25165824
□pga_aggregate_target = 30Mに変更
SQL> alter system set pga_aggregate_target=30M; システムが変更されました。 SQL> select distinct * from code where rownum<1000000; 経過: 00:00:58.25 SQL> select sql_text,operation_type,policy,last_memory_used/1024/1024,last_execution, last_tempseg_size from v$sql l,v$sql_workarea a where l.hash_value=a.hash_value and sql_text='select distinct * from code where rownum<1000000'; SQL_TEXT OPERATION_TYPE ------------------------------------------------ ---------------- select distinct * from code where rownum<1000000 GROUP BY (SORT) POLICY LAST_MEMORY_USED/1024/1024 LAST_EXECUTION LAST_TEMPSEG_SIZE ------ ---------------------------- -------------- ----------------- AUTO 1.5 2 PASSES 25165824
□pga_aggregate_target = 40Mに変更
SQL> alter system set pga_aggregate_target=40M; システムが変更されました。 SQL> select distinct * from code where rownum<1000000; 経過: 00:00:56.92 SQL> select sql_text,operation_type,policy,last_memory_used/1024/1024,last_execution, last_tempseg_size from v$sql l,v$sql_workarea a where l.hash_value=a.hash_value and sql_text='select distinct * from code where rownum<1000000'; SQL_TEXT OPERATION_TYPE ------------------------------------------------ ---------------- select distinct * from code where rownum<1000000 GROUP BY (SORT) POLICY LAST_MEMORY_USED/1024/1024 LAST_EXECUTION LAST_TEMPSEG_SIZE ------ ---------------------------- -------------- ----------------- AUTO 2 1 PASSES 25165824
□pga_aggregate_target = ほぼ最大値(4095G)に変更
SQL> alter system set pga_aggregate_target=4095G; システムが変更されました。 SQL> select distinct * from code where rownum<1000000; 経過: 00:00:51.81 SQL> select sql_text,operation_type,policy,last_memory_used/1024/1024,last_execution, last_tempseg_size from v$sql l,v$sql_workarea a where l.hash_value=a.hash_value and sql_text='select distinct * from code where rownum<1000000'; SQL_TEXT OPERATION_TYPE ------------------------------------------------ ---------------- select distinct * from code where rownum<1000000 GROUP BY (SORT) POLICY LAST_MEMORY_USED/1024/1024 LAST_EXECUTION LAST_TEMPSEG_SIZE ------ ---------------------------- -------------- ----------------- AUTO 35.75 OPTIMAL
□結論
pga_aggregate_targetの設定値を全て消費してしまうのではなく、
pga_aggregate_target * 5% を上限としてメモリを使用することができるよう
です。
この結果は以下のSQL文の結果からも推察できます。
SQL> select name,value/1024/1024 from v$pgastat where name in ('aggregate PGA target parameter','global memory bound'); NAME VALUE/1024/1024 ------------------------------ ------------------ aggregate PGA target parameter 10 global memory bound .5
マニュアルを参照すると、global memory boundは -自動モードで実行される
作業領域の最大サイズ-と記述されています。
この値を見るとaggregate PGA target parameter:10(M) * 5% = 0.5(M)となっ
ています。
どうして、設定値分を1プロセスで消費できないのでしょうか?
それはオラクルの仕様だからと言ってしまえば簡単ですが、1プロセスが消費
し尽くしてしまうと、それ以外のプロセスはディスクソートとなってしまい、
全体としてみた時のスループットがダウンしてしまうからでしょう。
では、仮に以下のようなシステムがあったとします。
夜間バッチに大きなソート処理が実行されている。
夜間帯は通常ほとんどバッチプロセス以外は実行されない。
pga_aggregate_targetの5%しか1プロセスにソートエリアがメモリに割り当て
られないのでは、ディスクソートとなってしまい処理の遅延が発生してしまう。
pga_aggregate_targetを大きくするほどメモリに余裕はない。
なんとかならないのか!!
┏ QUESTION ┓
?★ここで問題ですっ!どうするのでしょう?★?
┗ ┛
正解者の中から抽選で当メルマガの本を差し上げます。
下記のアドレスまで奮ってご応募くださいっ! (TI)
回答は次週!
今週はここまで。
以上、花粉警報発令中の茅ヶ崎にて