しばちょう先生の試して納得!DBAへの道 indexページ▶▶
みなさん、こんにちは。”しばちょう”こと柴田長(しばた つかさ)です。この4月はOracle OpenWorld Tokyo 2012が開催されて、多くの方にご参加頂けたかと思います。今回のイベントはスピーカーではなく一人の聴講者として多くのセッションに参加しましたが、いずれも素晴らしく興味深いものでした。特に、JPOUG(Japan Oracle User Group)のメンバーによって開催されたOracle OpenWorld Unconferenceのセッションは非常に刺激的な内容で、自分ももっと貪欲にOracle Databaseを触りたいと思わせられるものでした。

さて、第6回目の今回は前回の続きで、高度なSQLの実行計画の取得方法と性能差の確認方法をマスターしてみましょう。いざという時に、この辺りのコマンドをスラスラとタイピングできたりすると、それ以降、周囲から尊敬の眼差しで見られること間違いなしです。もちろん分析も出来ないといけないと威力半減ですが、まずは自分の指に記憶させてみてくださいね。
以下の演習をこれまでの演習で使用したOracle Database 11g Release 2 Enterprise Editionのデータベースで試してみてください。
■演習0.演習前の環境準備(第5回の演習終了後のデータベースの状態を今回の環境へ変更します)
今回初めて演習される方は、第4回の演習0~2を実行してから、以下のSQLを実行してください。各SQLを実行する目的については、第5回をご参照ください。
sqlplus / as sysdba SQL> alter system set FILESYSTEMIO_OPTIONS='SETALL' scope=spfile; shutdown immediate; startup @?/sqlplus/admin/plustrce.sql grant PLUSTRACE to TRY; grant select on V_$SESSION to TRY; grant select on V_$SQL_PLAN to TRY; grant select on V_$SQL to TRY; grant select on V_$SQL_PLAN_STATISTICS_ALL to TRY;
■演習1.SYSユーザーで共有プールをフラッシュして下さい。
sqlplus / as sysdba SQL> alter system FLUSH SHARED_POOL;
第5回 の演習1ではバッファ・キャッシュ上のデータをフラッシュしましたが、今回は共有プールが対象です。バッファ・キャッシュをフラッシュするSQL文が「alter system FLUSH BUFFER_CACHE ;」であったことを覚えていれば、マニュアル「SQL言語リファレンス」の「ALTER SYSTEM」セクション部分で簡単に見つけることが可能だと思います。
と言いつつも、この演習はSQL文の存在を知っておいてもらうことだけではなく、そもそも共有プールには何がキャッシュされているのかを復習して頂きたいと思っています。これは実行計画を取り扱う上で非常に重要であり、マニュアル「Oracle Database概要」の「共有プール」セクションと、マニュアル「パフォーマンス・チューニング・ガイド」の「7.3 共有プールとラージ・プールの構成及び使用方法」セクションをご一読されることをお勧めします。
詳細は上記のマニュアルをご参照頂くことにして、ここでは簡単に説明させて頂きます。共有プールのライブラリ・キャッシュにはSQL文の解析済み表現(実行計画等)が含まれています。SQL文を実行した際、実行計画が存在した(キャッシュされていた)場合は再利用(ソフト解析、ソフト・パース、ライブラリ・キャッシュ・ヒット)します。一方、存在しない場合には新たにハード解析(ハード・パース)を実行し、実行計画を作成することになります。
ちなみに私の経験では、数件のレコードを検索する数種類のSELECT文が数千ユーザーから頻繁に実行されるOLTP系のデータベースにおいて、毎回のSQL実行の度にハード・パースが行われていた状態をソフト・パースにチューニングすることで、CPU使用率が半分程度まで削減できたことがあります。1つの実行計画が作成されるのは数ミリ秒~数十ミリ秒の世界ではありますが、その過程では何十、何百通りもの実行計画候補の評価が行われ、その中で一番効率的にレコード戻す実行計画が選択されます。つまり、ハード・パースではそれなりのCPUパワーを消費するように感じてもらえると思います。だからこそ、実行時間が数十ミリ秒~数百ミリ秒のように短いSQLを繰り返し実行するようなOLTP系のデータベースでは、実行計画をキャッシュして使いまわすソフト・パースが重要になってくるのです。ただし、誤解して頂きたくない点としては、ハード・パースがいつでも悪ではないということです。例えば単発SQLの実行時間が数秒~数十秒、数百秒と長くなる傾向がある夜間バッチ処理やData Warehouse系のデータベースでは、数ミリ秒のハード・パースは埋もれてしまいますよね。実際の共有プールの詳細なチューニング方法については、津島博士のパフォーマンス講座「第7回 共有プールについて」をご参照ください。
さて、説明が長くなってしまいましたが、そろそろ話を演習に戻します。
共有プールをフラッシュすることでキャッシュされている実行計画を消すことができるので、パフォーマンス検証を実施する前にはバッファ・キャッシュのフラッシュと併せて実行する癖をつけておきましょう。共有プール内の断片化を解消してORA-4031エラーの発生を抑制すること目的として実行されるケースもありますが、これには十分注意する必要がある点を補足しておきます。共有プール内の断片化はOracle Databaseのバージョンが上がるにつれて発生し難いように改善され続けており、もしOracle Database 11gでOra-4031エラーが発生した場合は、フラッシュを行う運用を含めるのではなく、共有プールのサイズ拡張をお勧めします。それでも運用中に共有プールのフラッシュを実行しなければならない場合には、データベースに対する負荷が低い時間帯での実行をお勧めします。フラッシュを実行する際にはデータベース内でロック機構が動作すること、さらにフラッシュ後にはハード・パースが頻発することを考えると、オンライン・トランザクションへの性能影響を必ず検討・テストしてください。
■演習2.TRYユーザーでTBL2表に対するSELECTを1度実行して下さい。
sqlplus TRY/TRY SQL> select /* practiceSQL1 */ COL1 || ' : ' || COL2 "Record" from TBL2 where ROWNUM <=3 ; Record -------------------------------------------------------------------------------------------- 1 : 1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 : 2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 3 : 3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
はい、簡単ですね。どのようなSELECT文でも良いのですが、折角の機会なので私の回答では3つほど簡単なテクニックを含めてみました。
まず一つ目は「コメント」です。回答例のSQL文では「/* practiceSQL1 */」というコメントを含めています。開発者の好みにもよりますが、SQL文中にコメントを含めておくとアプリケーションのコードを読み易くしたり、メンテナンスし易くしたりすることが可能です。実行計画を操作する目的のヒント句は特別ですが、コメントはSQL文に影響を与えません。なので、ヒント句にスペルミスがあってもコメントとして扱われるだけであり、ORAエラーは発生しませんよね。
二つ目は「連結演算子」です。「||」を使用することで複数の列データの戻り値を連結することが可能です。回答例では、さらにCOL1とCOL2の列データの間にシングル・コーテーションで囲んだ文字列「 : 」を埋め込んであります。例えば、DBAの業務を考えた場合、ある表に作成されている全ての索引を再作成(Rebuild)するSQL文を作る際にこのテクニックを使用したりしますね。
SQL> select 'alter index ' || INDEX_NAME || ' rebuild;' from USER_INDEXES where TABLE_NAME='TBL2'; 'ALTERINDEX'||INDEX_NAME||'REBUILD;' --------------------------------------------------- alter index PK_TBL2_COL1 rebuild; SQL> alter index PK_TBL2_COL1 rebuild; 索引が変更されました。
ちなみにマニュアルにも記載がありますが、異なるキャラクタ・セットを持つOS環境間で連結演算子を含むSQLを共有するような場合、垂直バーが正しく変換されない可能性があります。そのような場合には、文字列を連結するCONCATファンクションの使用をお勧めします。
三つ目は「ROWNUM疑似列」です。回答例のSQL文では「where ROWNUM <=3」が設定されているので、問い合わせによって戻される行数を「3」に制限しています。
これらの詳細については、SQL言語リファレンスの「SQL文中のコメント」、「連結演算子」、「ROWNUM疑似列」をご参照ください。これまで普通に使用していたものでも、改めてマニュアルを読んでみると新しい発見があるものですよね。
■演習3.V$SQLに問い合わせて、演習2で実行したSELECT文のSQL_IDとCHILD_NUMBERを確認して下さい。
sqlplus / as sysdba SQL> set pagesize 100 linesize 120 col SQL_TEXT for a90 select SQL_ID, CHILD_NUMBER, SQL_TEXT from V$SQL where SQL_TEXT like 'select /* practiceSQL1 */ COL1 || '' : '' || %' ; SQL_ID CHILD_NUMBER SQL_TEXT ------------- ------------ ---------------------------------------------------------------------------------------- 2vrywhbx1jxtb 0 select /* practiceSQL1 */ COL1 || ' : ' || COL2 "Record" from TBL2 where ROWNUM <=3
さあ、いよいよ本番です。動的パフォーマンス・ビューV$SQL内から演習2で実行したSELECT文を見つけることはそれほど難しくなかったかと思います。しかし、そもそもV$SQLにはどのような情報が格納されているのでしょうか。というところで、リファレンス・マニュアルを見てみることにしましょう。目次のページには初期化パラメータ名やビュー名が掲載されているので、ブラウザの文字列検索機能で簡単にヒットさせることが可能です。(ただし、統計情報とバックグラウンド・プロセスについては一段下がる必要有ります)
V$SQLの説明書きを以下に抜粋してみます。
V$SQLは、GROUP BY句のない共有SQL領域についての統計情報を示し、入力された元のSQLテキストの子ごとに1行ずつ表示します。V$SQLに表示される統計情報は、通常、問合せの実行が終了した時点で更新されます。ただし、問合せの実行が長期にわたる場合は、5秒ごとに更新されます。これによって、実行中に、長時間実行されるSQL文の影響を容易に確認できます。
V$SQLは共有プールのライブラリ・キャッシュに含まれる共有SQL領域内の情報が含まれていることが理解できます。つまり、V$SQLに問い合わせるということは、共有プール内を参照するということになります。ちなみに、文頭に少し分かりづらい表現がありますが、「GROUP BY句のないSQL文」という意味ではなく「GROUP BYでまとめていない共有SQL領域の情報」という意味だと思います。そして、中間から後半にかけて興味深い情報が記載されていますね。意外とベテランDBAの方でも知らない情報なので、若手の皆さんは是非とも自慢してみましょう。
ついでに、このV$SQLから確認できる情報をもう少し見てみましょう。
sqlplus / as sysdba SQL> set pagesize 100 linesize 120 col LAST_LOAD_TIME for a20 col PARSING_SCHEMA_NAME for a4 col MODULE for a8 select SQL_ID, CHILD_NUMBER, LAST_LOAD_TIME, EXECUTIONS, PARSING_SCHEMA_NAME, MODULE, CPU_TIME, ELAPSED_TIME from V$SQL where SQL_ID = '2vrywhbx1jxtb'; SQL_ID CHILD_NUMBER LAST_LOAD_TIME EXECUTIONS PARS MODULE CPU_TIME ELAPSED_TIME ------------- ------------ -------------------- ---------- ---- -------- ---------- ------------ 2vrywhbx1jxtb 0 2012-04-23/15:42:23 1 TRY SQL*Plus 169974 1178483
参考までに上記のSQLで参照した列を説明させて頂きます。LAST_LOAD_TIME列は、分析対象のSQLがライブラリ・キャッシュにロードされた時刻をしており、いつハード・パース(実行計画が作成)されたのかを読み取ることが可能です。EXECUTIONS列はその名の通り分析対象のSQLが実行された回、PARSING_SCHEMA_NAME列は実行計画の作成に使用されたスキーマ名、MODULE列はハード・パースを実行した際にSQL文を投げたモジュール名を示しています。CPU_TIME列はこのSQLを処理する為に要した合計CPU時間(マイクロ秒)、ELAPSED_TIME列はSQLを処理する為に要した合計経過時間(マイクロ秒)です。これらは全てマニュアルに記載されています。
-- TRYユーザーで演習2のSELECT文をさらに5回実行後
SQL>
select SQL_ID, EXECUTIONS, PARSE_CALLS,
CPU_TIME, ELAPSED_TIME, ELAPSED_TIME - CPU_TIME,
USER_IO_WAIT_TIME, DISK_READS,PHYSICAL_READ_BYTES
from V$SQL
where SQL_ID = '2vrywhbx1jxtb';
SQL_ID EXECUTIONS PARSE_CALLS CPU_TIME ELAPSED_TIME ELAPSED_TIME-CPU_TIME USER_IO_WAIT_TIME DISK_READS PHYSICAL_READ_BYTES
------------- ---------- ----------- ---------- ------------ --------------------- ----------------- ---------- -------------------
2vrywhbx1jxtb 6 6 219966 1313478 1093512 1164674 390
TRYユーザーで演習2のSELECT文をさらに5回実行した後のV$SQLに問い合わせしてみると、上記のような結果が出力されます。EXECUTIONS列の「6」はSELECT文を実行した合計回数6回と一致していますし、合計パース回数を示すPARSE_CALLS列も「6」で正しい(おそらく、ハード・パース1回、ソフト・パース5回)です。
CPU_TIME列の値が前回(EXECUTIONS=1の場合)の「169974」から今回(EXECUTIONS=6)は「219966」へ増加してはいますが、6倍にはなっていないことに気付かれた方は毎度お馴染みの鋭い方です。まさにこの差はハード・パースとソフト・パースの違いによるものですね。
あれ?CPU_TIME列とELAPSED_TIME列が一桁違ますね?今回の演習からは脱線してしまいますが、この差(ELAPSED_TIME – CPU_TIME)の原因を理解することがパフォーマンス・チューニングを実施する上で非常に重要になりますので、解説しておきます。
SQLの処理で要したCPU時間と経過時間の差が生まれる理由としては大きく三つあります。一つはHDDからのデータ・ブロックの読み込み待ちが発生しCPUが使えない時間があること。もう一つは同様にネットワーク転送の待機でCPUが使えない時間があること。最後の一つは、CPU使用率が100%の状態でCPUを使いたくても使えない時間があることです。これらの切り分けとしてはOS層でのCPU使用率やネットワーク転送量を分析するのも手ですが、今回の演習ではV$SQLのUSER_IO_WAIT_TIME列(I/O待機時間(マイクロ秒))が「ELAPSED_TIME – CPU_TIME」とほぼ同じ値を示しているので、一つ目のデータ・ブロックの読み込み待ちが原因であると判断できます。ちなみに、DISK_READS列(読込ブロック数)やPHYSICAL_READ_BYTES列(HDDから読み込んだバイト数)からも実際にHDDからの読み込みが発生していたことが確認できます。EXECUTIONS=1の場合とEXECUTIONS=6の場合で「ELAPSED_TIME – CPU_TIME」の値が大きく変化していない理由は、EXECUTIONS=1の際にデータ・ブロックをバッファ・キャッシュにキャッシュし、2回目以降はHDDからブロックを読み込んでいない(つまり、ブロックの読み込み待ちが発生していない)と読み解くことができます。
■演習4.DBMS_XPLAN.DISPLAY_CURSORファンクションを使用して、演習2で実行したSELECT文の実行計画を確認して下さい。
sqlplus TRY/TRY
SQL> set linesize 100 pagesize 100
select * from table(DBMS_XPLAN.DISPLAY_CURSOR('2vrywhbx1jxtb', 0));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID 2vrywhbx1jxtb, child number 0
-------------------------------------
select /* practiceSQL1 */ COL1 || ' : ' || COL2 "Record" from TBL2
where ROWNUM <=3
Plan hash value: 2810601966
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 4 (100)| |
|* 1 | COUNT STOPKEY | | | | | |
| 2 | TABLE ACCESS FULL| TBL2 | 920K| 57M| 4 (50)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=3)
Note
-----
- dynamic sampling used for this statement (level=2)
PL/SQLパッケージのプロシージャやファンクションの詳細はマニュアル「PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス」に記載されているので、「DBMS_XPALNパッケージのDISPLAY_CURSORファンクション」を参照してみます。大抵の場合、構文/パラメータ/使用上の注意/例が記載されています。また、実行で必要となる各パラメータに指定する値は演習3で取得済みですから、問題なく実行できたかと思います。
マニュアルのformatパラメータの説明部分にも説明がある通り、指定の仕方次第では様々な情報を出力させることが可能です。今回は説明を割愛しますが、機会があればもう少し詳細に解説しますね。My Oracle Supportにアクセス可能な方は、KROWN# 141531を参照してみてください。便利な世の中になったと感じて頂けるでしょう。
■演習5.SQL*Plusを使用して、DBMS_SQLTUNEパッケージ内の全プロシージャとファンクションを確認して下さい。
sqlplus TRY/TRY SQL> desc DBMS_SQLTUNE FUNCTION ACCEPT_SQL_PROFILE RETURNS VARCHAR2 引数名 タイプ In/Out Default? ------------------------------ ----------------------- ------ -------- TASK_NAME VARCHAR2 IN OBJECT_ID NUMBER IN DEFAULT NAME VARCHAR2 IN DEFAULT DESCRIPTION VARCHAR2 IN DEFAULT CATEGORY VARCHAR2 IN DEFAULT TASK_OWNER VARCHAR2 IN DEFAULT REPLACE BOOLEAN IN DEFAULT FORCE_MATCH BOOLEAN IN DEFAULT PROFILE_TYPE VARCHAR2 IN DEFAULT PROCEDURE ACCEPT_SQL_PROFILE 引数名 タイプ In/Out Default? ------------------------------ ----------------------- ------ -------- TASK_NAME VARCHAR2 IN ..................
はい、今更で恐縮ですが、パッケージ内に含まれるプロシージャやファンクション、及びそれらの引数等を確認したい場合には、「DESC[RIBE] パッケージ名」で出力させることができますね。少し長いので出力結果を省略していますが、次の演習6で使用するDBMS_SQLTUNE.REPORT_SQL_MONITORファンクションの部分を抜粋したものが次です。各引数が何を意味するのか、何を指定できるのかは、先程と同様にマニュアル「PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス」の「DBMS_SQLTUNEパッケージのREPORT_SQL_MONITORファンクション」をご参照ください。
FUNCTION REPORT_SQL_MONITOR RETURNS CLOB 引数名 タイプ In/Out Default? ------------------------------ ----------------------- ------ -------- SQL_ID VARCHAR2 IN DEFAULT SESSION_ID NUMBER IN DEFAULT SESSION_SERIAL NUMBER IN DEFAULT SQL_EXEC_START DATE IN DEFAULT SQL_EXEC_ID NUMBER IN DEFAULT INST_ID NUMBER IN DEFAULT START_TIME_FILTER DATE IN DEFAULT END_TIME_FILTER DATE IN DEFAULT INSTANCE_ID_FILTER NUMBER IN DEFAULT PARALLEL_FILTER VARCHAR2 IN DEFAULT PLAN_LINE_FILTER NUMBER IN DEFAULT EVENT_DETAIL VARCHAR2 IN DEFAULT BUCKET_MAX_COUNT NUMBER IN DEFAULT BUCKET_INTERVAL NUMBER IN DEFAULT BASE_PATH VARCHAR2 IN DEFAULT LAST_REFRESH_TIME DATE IN DEFAULT REPORT_LEVEL VARCHAR2 IN DEFAULT TYPE VARCHAR2 IN DEFAULT SQL_PLAN_HASH_VALUE NUMBER IN DEFAULT
■演習6.DBMS_SQLTUNE.REPORT_SQL_MONITORファンクションを使用して、演習2で実行したSELECT文のリアルタイムSQL監視のHTML形式のレポートを生成して下さい。
まずはDBMS_SQLTUNE.REPORT_SQL_MONITORファンクションを実行する為に必要とされる幾つかのビューに対するSELECT権限を付与する必要があります。今回はロール「SELECT_CATALOG_ROLE」を使用して権限を付与します。
qlplus / as sysdba SQL> grant SELECT_CATALOG_ROLE to TRY;
では、HTML形式のレポートを作成してみましょう。
sqlplus TRY/TRY SQL> set trimspool on set trim on set pages 0 select /* practiceSQL1 */ COL1 || ' : ' || COL2 "Record" from TBL2 where ROWNUM <=3 ; -- アクティブ・レポートの作成 set linesize 1000 set long 1000000 set longchunksize 1000000 spool sqlmon_active.html select dbms_sqltune.report_sql_monitor(sql_id=>'2vrywhbx1jxtb', type=>'active') from dual; spool off
DBMS_SQLTUNE.REPORT_SQL_MONITORファンクション実行する際に、typeパラメータに「HTML」もしくは、「ACTIVE」を設定することでHTML形式のレポートが出力されるので、SQL*PlusのSOOLコマンドで出力結果を保存します。
作成されたアクティブ・レポートは、Oracle Enterprise Manager(以降、EM)と類似したインターフェースですが、EMのインストールは不要です。ただし、このレポートをWebブラウザで表示する際にはUS OTNからコードを読み込む必要がある為、インターネット接続が必要とされています。
さて如何でしょうか?無事、アクティブ・レポートを取得+表示させることはできましたか?
私と同じSELECT文を実行されていた方は、上記のような空っぽのレポートが表示されてしまったかと思います。これは正しい動作なのでご安心くださいね。理由としては、今回演習2で実行したSELECT文の実行時間が5秒未満で完了する為、監視の対象から外れている為です。パフォーマンス・チューニング・マニュアルの「リアルタイムSQL監視」に説明書きがあるように、最低5秒以上のCPU時間またはI/O時間を消費すると自動的に監視対象になります。これは基本的にはOLTP系のSQLは監視対象にならず、バッチ処理やData Warehouse系のSQLが対象になる傾向があるということです。 もちろん、OLTP系のSQLでも索引不足等の問題で異常に長時間レスポンスが戻ってこない場合は監視対象になり得るので、問題発生時の分析ツールとして活用できると思います。
では、今回強制的に監視の対象とする方法をご紹介しておきます。
sqlplus TRY/TRY SQL> -- 監視対象SQLの実行 set trimspool on set trim on set pages 0 select /*+ MONITOR */ /* practiceSQL2 */ COL1 || ' : ' || COL2 "Record" from TBL2 where ROWNUM <=3 ; -- SQL_IDの特定 SQL> connect / as sysdba set pagesize 100 linesize 120 col SQL_TEXT for a100 select SQL_ID, CHILD_NUMBER, SQL_TEXT from V$SQL where SQL_TEXT like 'select /*+ MONITOR%' ; SQL_ID CHILD_NUMBER SQL_TEXT ------------- ------------ ---------------------------------------------------------------------------------------------------- crf5a18jws344 0 select /*+ MONITOR */ /* practiceSQL1 */ COL1 || ' : ' || COL2 "Record" from TBL2 where ROWNUM <=3 -- レポートの作成(SYSユーザー、TRYユーザーのどちらでも良い) set linesize 1000 set long 1000000 set longchunksize 1000000 spool sqlmon_active.html select dbms_sqltune.report_sql_monitor(sql_id=>'crf5a18jws344', type=>'active') from dual; spool off
上記の回答例のように、監視したいSQL文内に「MONITOR」ヒントを埋め込むことで、強制的に監視させることが可能です。逆に、監視対象から外したい場合には、「NO_MONITOR」ヒントを使用します。ただし「MONITOR」ヒントは、初期化パラメータ「CONTROL_MANAGEMENT_PACK_ACCESS」の値が「DIAGNOSTIC+TUNING」に設定されている場合にのみ有効になることにご注意ください。
上記のようなレポートが作成できていれば成功です。SQLの実行時間が非常に短いので情報が取得できていないページもありますから、そこはご了承くださいね。お時間がある方は、是非、長時間を要するSQL文を使用して復習をしてみてください。リアルタイムSQL監視については「OTN」や「シバタツ流! DWHチューニングの極意 第5回」にも情報が掲載されていますので参考にしてみてください。
※リアルタイムSQL監視はDiagnostics Pack + Tuning Packオプションの機能です。
さて、前回と今回の2回に渡りご紹介させて頂いた実行計画の取得は如何だったでしょうか。ご認識頂いていると思いますが、あくまで実行計画の取得とはトラブル・シューティングの第一歩にしかすぎません。しかし、その後の分析作業をスムーズに進める上の基本となる作業であり、正確性が求められる作業でもあります。冒頭での説明と重複しますが、是非ご自分の指に記憶させるぐらいSQL文を叩きまくって頂きたいというのが私の願いです。タイピングミスをすることなく、スラスラと実行計画を取得することができるようになったら、きっとDBAとしてのプライドが少しずつ育ってきていると思います。
毎度、長文にも関わらず最後まで読んで頂きまして、ありがとうございました。


