JPOUGに参加させていただきました!

インサイトテクノロジーの新久保さんの想いに共感し、[Japan Oracle User Group – JPOUG](http://www.jpoug.org/) にメンバーとして参加させていただきました!

Oracle Database Userのみなさんに役立つ活動を行っていきたいと思います!
何かご意見がありましたら、twitterやblogのコメント欄で頂戴できればうれしいです!

実行計画のツリーのたどり方 (実行計画の読み方#1)

これまでのエントリに記載してきたように、実行計画は階層的なツリー構造で表現
されます。
本エントリでは、実行計画の読み方のfirst stepとして、
実際の処理順序に即したツリー構造のたどり方を説明します。

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, ‘LAST’));

PLAN_TABLE_OUTPUT
———————————————————————————————
SQL_ID dvv5bah5b4k51, child number 1
————————————-
SELECT /*+ FULL(PA) INDEX(CH idx_chpa) USE_NL(CH) LEADING(PA) */ cid,
cname, pa.pid, pname FROM ch, pa WHERE ch.pid = pa.pid and pa.pid
= 1

Plan hash value: 3514264536

—————————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————————–
| 0 | SELECT STATEMENT | | | | 20 (100)| |
| 1 | NESTED LOOPS | | 10 | 40120 | 20 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | PA | 1 | 2004 | 9 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| CH | 10 | 20080 | 11 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | IDX_CHPA | 10 | | 1 (0)| 00:00:01 |
—————————————————————————————–

Predicate Information (identified by operation id):
—————————————————

2 – filter(“PA”.”PID”=1)
4 – access(“CH”.”PID”=1)

24 rows selected.

### 実行計画のツリー構造とオペレーションの親子関係

実行計画は、一般に複数のオペレーションから構成されます。オペレーションは、親子関係に
したがってインデントして整形されたツリー構造となります。

たとえば、上記の実行計画は、NESTED LOOPS, TABLE ACCESS FULL などのオペレーション
から構成されます。(オペレーションの種類と処理内容については次のエントリで説明します。)

オペレーションの親子関係についてですが、
Id=1 NESTED LOOPSは Id=2 TABLE ACCESS FULLと、Id=3 TABLE ACCESS BY INDEX ROWID
の親となります。同様に Id=3 TABLE ACCESS BY INDEX ROWID
Id= 4 INDEX RANGE SCAN の親となります。

Id=0 SELECT STATEMENT

│行ソース

Id=1 NESTED LOOPS
↑ ↑
行ソース┌─────┘ └─────┐行ソース
│ │
Id=2 TABLE ACCESS FULL Id=3 TABLE ACCESS BY INDEX ROWID

│行ソース

Id=4 INDEX RANGE SCAN

それぞれのオペレーションは、行ソースとよばれる表から取得した行データ(のサブセット)を出力します。
親オペレーションは子オペレーションの行ソースを入力として処理を行います。

概念的な説明だけではわかりにくいので、先の実行計画がどのように処理されるかを
イメージしながら、読み方を説明してみましょう。

Continue reading 実行計画のツリーのたどり方 (実行計画の読み方#1)

実行計画の読み方

これまでのエントリで、DBMS_XPLAN.DISPLAY_CURSORをつかってV$SQL_PLAN
から実行計画を取得する方法をオススメしてきました。
この方法は、手軽であり、かつ、SQLトレースやEXPLAIN PLANの問題点に対処できる
優れた方法であることがお分かりいただけたかと思います。

しかし、当たり前の話ですが、実行計画を取得できたとしても、読めなければ意味がありません。
このため、取得した実行計画の読み方をこれからいくつかのエントリで説明したいと思います。

以下の構成で進める予定です。(エントリ記載次第、リンクを張る予定)

* [実行計画のツリーのたどり方](http://www.csus4.net/d/2011/06/20/traverse_plan_tree/)
* [オペレーションの一覧と最低限覚えておくべきオペレーション](http://www.csus4.net/d/2011/06/30/operations/)
* [フィルタ述語とアクセス述語](http://www.csus4.net/d/2011/06/30/predicate/ )
* 結合の動作イメージとオペレーション

自身の経験上、実行計画の読み方は一度の説明で理解しにくいようです。
このため、一連のエントリでは、わざと同じようなことを何度も繰り返し説明するような
形にしています。

SQLチューニングアドバイザの代用品としての動的サンプリング

[先のエントリ]( http://www.csus4.net/d/2011/04/30/check_cbo/ )
で、実行計画の見積もりミスの可能性を調べるため、CBOの見積もり行数と実行時行数の
差異をチェックする方法をお伝えしました。
実際にCBOの見積もり行数と実行時行数の差異が大きいSQLを見つけた場合は、
現在使用している実行計画が最適かどうか、最適な実行計画はどのようなものかを
検討する必要が出てきます。

しかし、この作業は簡単なものではありません。
[先のエントリ]( http://www.csus4.net/d/2011/04/30/check_cbo/ )
の例は、1つのテーブルにのみアクセスするきわめてシンプルなものであり、
テーブルスキャン(TABLE ACCESS FULL)
よりもインデックススキャン (INDEX RANGE SCAN)
が効率的であるとすぐにわかりました。
しかし、通常のアプリケーションではSQLはもっと複雑であり、
最適な実行計画の検討は、Oracle Databaseに関するSQLチューニングスキルが必要であり、時間もかかる作業です。

Oracle Database 9.2 以前など、アドバイザ機能が充実していなかったバージョンを
使用していたときは、スキルを持ったデータベースエンジニアが、さまざまな角度から
検討し、最適と思われる実行計画を検討していたと思います。
この作業は、実際に効果が得られるかどうか不透明なわりに、時間と労力を要する非効率的なものでした。
チューニング作業は、時間をかければかけただけ、必ず改善されるという保障があるわけではないという
側面があるからです。

Oracle Database 10g以後では、アドバイザ機能が充実し、SQLチューニングアドバイザ
を活用して、Oracle Database が自動的に最適な実行計画を作成してくれるように
なっており、作業コストを大幅に削減できます。
しかし、SQLチューニングアドバイザを使用するためには Enterprise Edition の利用に
くわえて、別売のオプション機能 Diagnostic Pack と Tuning Packが必要であるため、
使用できる人が限られるのが現実ではないでしょうか。

### 動的サンプリングによる最適な実行計画検討の自動化

実は、動的サンプリングという機能を使うことで、SQLチューニングアドバイザが使用で
きない場合でも、最適と思われる実行計画の検討をOracle Database任せにすることが
できます。

Continue reading SQLチューニングアドバイザの代用品としての動的サンプリング

DISPLAY_CURSORでCBOの見積りミスを簡単に確認する

前回のエントリで
DBMS_XPLAN.DISPLAY_CURSOR の format引数に’TYPICAL’と
‘ALL ALLSTATS LAST’ を主に指定すると説明しました。
本エントリでは、format引数 ‘ALL ALLSTATS LAST’の機能を説明し、
その一例として、CBOの見積りミスを簡単に確認することができることを説明したいと思います。

### format引数 ‘ALL ALLSTATS LAST’
format引数 ‘ALL ALLSTATS LAST’を指定すると、
実行計画ツリーを示す PLAN_TABLE_OUTPUT、
フィルタ条件やアクセス情報を示す Predicate Informationに加えて、
複雑なSQLを分割したクエリブロック情報や表のエイリアス情報を示すQuery Block Name / Object Alias、
アクセスした列に関する情報を示すColumn Projection Information が表示されます。

また、PLAN_TABLE_OUTPUTの列に、オペレーション単位の各種実行統計が追加されます。
format引数’TYPICAL’を指定した場合は、確認できるのはCBOによって見積もられた見積統計
(見積もり行数、見積もりバイトなど)しか確認できませんでしたが、
実行時の実行統計(実際にオペレーションを実行した結果得られた行数など)
が確認できます。

また、format引数 ‘LAST’が指定されていることで、
直近のSQL実行の統計情報を表示します。
逆に’LAST’を指定しないと、得られる統計情報が共有カーソル単位の累積値となってしま
い(同じSQLを複数回実行すると複数回実行分の合算値となる)、1回実行分の統計を確認したい
ような通常の用途では不適切であることに注意してください。

なお、前回のエントリで説明しましたが、format引数 ‘ALLSTAT’、’LAST’は
調査対象のSQLの実行前にstatistics_levelパラメータをALLに設定するか、
SQLに /*+ gather_plan_statistics */ ヒントを指定した場合でのみ有効となる
ことに注意してください。

### CBOの見積もりミスを確認する

このように、format引数 ‘ALL ALLSTATS LAST’ を指定したDBMS_XPLAN.DISPLAY_CURSOR
を用いて実行計画を取得すると、様々な情報が取得できます。

CBOが作成した実行計画が、本当に最適な実行計画であるか疑問がある場合には、
オペレーション単位で確認できる様々な統計の1つである見積行数(E-Rows)と
実行時行数(A-Rows)が非常に有効です。

Continue reading DISPLAY_CURSORでCBOの見積りミスを簡単に確認する

DBMS_XPLAN.DISPLAY_CURSORの使い方とちょっとした落とし穴

先日のエントリ
[SQLパフォーマンス問題調査でEXPLAIN PLAN、SQLトレースは(ほとんど)使わない](http://www.csus4.net/d/2011/02/24/whynotuse_explainplan_sqltrace/)
でお勧めしたDBMS_XPLAN.DISPLAY_CURSORについて、基本的な使い方を説明します。

### 基本的なDBMS_XPLAN.DISPLAY_CURSORの使い方

詳細はマニュアル(Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス)
のDBMS_XPLANパッケージの箇所をご確認いただきたいのですが、

* 10.2 : [DISPLAY_CURSORファンクション](http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19245-02/d_xplan.htm#i998364)
* 11.1 : [DISPLAY_CURSORファンクション](http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/appdev.111/E05686-02/d_xplan.htm#i998364)
* 11.2 : [DISPLAY_CURSORファンクション](http://download.oracle.com/docs/cd/E16338_01/appdev.112/b56262/d_xplan.htm#i998364)

DISPLAY_CURSORファンクションには以下の引数を指定します。

DBMS_XPLAN.DISPLAY_CURSOR(
sql_id IN VARCHAR2 DEFAULT NULL,
child_number IN NUMBER DEFAULT NULL,
format IN VARCHAR2 DEFAULT ‘TYPICAL’);

sql_id: SQLの識別子
child_number : 子カーソル番号
format: 出力フォーマット(後ほど簡単に説明)

このファンクションはテーブルファンクションであるため、TABLE演算子で変換すると
通常の表のように扱えます。典型的には引数sql_idに調査対象のSQLのsql_idを指定して、
以下のように使用します。
Continue reading DBMS_XPLAN.DISPLAY_CURSORの使い方とちょっとした落とし穴

SQLパフォーマンス問題調査でEXPLAIN PLAN、SQLトレースは(ほとんど)使わない

Oracle DatabaseのSQLパフォーマンス問題が発生したときの、実行計画の取得についてまとめます。

SQLパフォーマンス問題が発生したときに、まず確認すべき情報はSQLの実行計画ですが、
Oracle Databaseには、実行計画を確認する方法が、大きく分けて3つあります。

* EXPLAN PLAN : (一般にSQL*Plusから)EXPLAN PLAN FOR < 実行したいSQL>を実行して、実行計画を確認します。
* SQLトレース : SQLの実行前にalter session sql_trace=true;を実行して、トレースファイルに出力された情報から実行計画を確認します。
* DBMS_XPLAN.DISPLAY_CURSORプロシージャ : 共有プールに保管された共有カーソルの情報から、実行計画を確認します。共有カーソルが共有プールからage-outされた場合、実行計画は確認できません。

### EXPLAIN PLANとSQLトレースを使わない理由

従来から存在しており、かつ、広く知られている実行計画の取得方法は、
EXPLAIN PLANとSQLトレースの2つです。しかし、私がOracle DatabaseのSQLパフォーマンス問題
に対応する場合、これらの2つの方法は原則的に使いません。

これら2つの方法には、いくつか使いにくい点があるからです。
Continue reading SQLパフォーマンス問題調査でEXPLAIN PLAN、SQLトレースは(ほとんど)使わない

優れたカーソル共有があればバッチ処理SQLのリテラル化は不要か?

[先日のエントリ](http://www.csus4.net/d/2010/12/29/batch_sq/) に、
Oracle Database 11.1 からは優れたカーソル共有(ACS, Adaptive Cursor Sharing, 適用カーソル共有)
という機能が導入されているため、エントリの内容が当てはまらないと書きました。
優れたカーソル共有が機能すると、バインド変数化されたSQLと共有カーソルの対応関係が異なってきます。

具体的には、従来(10.2以前)では、バインド変数値によらず、
原則的にバインド変数化されたSQLと共有カーソルは1対1関係にありましたが、
11.1で優れたカーソル共有が機能する(デフォルトで有効)と、
バインド変数に指定された値によって、既存の共有カーソル(≒実行計画)を使用
すべきでないとOracleが判断すると、新規に別の共有カーソル(≒実行計画)を作成し、
SQL実行にこの共有カーソルを使用します。
すなわち、バインド変数化されたSQLと共有カーソルは1対多の関係となる可能性があります。

(*1) ここの説明において、共有カーソルは子カーソルを指します。

### では、優れたカーソル共有により、意図しない実行計画が使用される事態を予防できるか?
Continue reading 優れたカーソル共有があればバッチ処理SQLのリテラル化は不要か?

突然のSQLパフォーマンスダウンを防ぐためのバッチ処理SQLリテラル化のススメ

またまた前回の更新から時間が空いてしまいました・・・。
いろいろと忙しく時間が取れないのですが、このままだと2010年まったくblogを書いていないことになってしまうのと、
twitterで後押しをいただいたこともあり、何とか書き上げました。お役に立てば幸いです。

### はじめに

最近、Oracle Databaseのパフォーマンスに関連するトラブルシューティング
を担当することが多いのですが、特に多い事例が、
ある特定のSQLのパフォーマンスが突然ダウンするような問題です。

原因はいろいろなのですが、バッチ処理で実行されるSQLに、バインド変数
を使用しているためにパフォーマンスが突然ダウンしてしまった状況が多くみられました。
(もちろんケースバイケースの側面はありますが、)バッチ処理で実行されるSQLは
一般的にバインド変数化するべきではありません。
SQLをバインド変数化することにはメリットもありますが、デメリットもあります。
特に、デメリットの部分が広く知られていないため、プログラムをコーディング
するときに、開発者がある種機械的・盲目的にSQLをバインド変数化していることが
この問題の背景にあるのではと思っています。

本エントリでは、SQLをバインド変数化のメカニズムと
SQLをバインド変数化することのメリットとデメリットを説明した上で、
バッチ処理で実行されるSQLをリテラルSQL化することをお勧めします。
Continue reading 突然のSQLパフォーマンスダウンを防ぐためのバッチ処理SQLリテラル化のススメ

書籍 「プロとしてのOracle運用管理入門」を執筆しました

すみません、前回のエントリから5ヶ月近く間が空いてしまいました。
この間何をしていたかというと、(必死の思いで・・・)2冊めの書籍を執筆しておりました。
先に執筆した書籍「プロとしてのOracleアーキテクチャ入門」と同じ「プロとしてのOracle・・・」
シリーズの第8弾「プロとしてのOracle運用管理入門」です。
おそらく9/24ごろから書店に並ぶ予定です。

プロとしてのOracle運用管理入門
株式会社コーソル 渡部 亮太
ソフトバンククリエイティブ
売り上げランキング: 320943

* [ソフトバンククリエイティブの本:プロとしてのOracle運用管理入門](http://www.sbcr.jp/books/products/detail.asp?sku=4797355123)

「運用管理」という非常に幅の広い題材であることから、原稿のボリュームが一時500
ページ以上に達してしまいましたが、編集のOさんの「超・編集力」のおかげで、なんとか
416ページにまとめ上げることができました。Oさん、ありがとうございます!

### 目次

* Part1 データベース管理者の役割とOracleの起動・停止
* CHAPTER 01 データベース管理者の役割
* CHAPTER 02 Oracleの起動・停止

* Part2 領域管理
* CHAPTER 03 領域管理の全体像と永続表領域の管理
* CHAPTER 04 UNDO表領域の管理
* CHAPTER 05 一時表領域の管理

* Part3 オブジェクトの管理
* CHAPTER 06 テーブルの管理
* CHAPTER 07 索引の管理
* CHAPTER 08 その他のオブジェクトの管理

* Part4 ユーザー管理と監査
* CHAPTER 09 ユーザー管理
* CHAPTER 10 監査

* Part5 パフォーマンスの管理
* CHAPTER 11 パフォーマンス管理の概要とStatspackレポートの分析
* CHAPTER 12 メモリの管理
* CHAPTER 13 実行計画とオプティマイザ統計
* CHAPTER 14 SQLチューニングの基本

* Part6 バックアップ/リカバリとデータ管理
* CHAPTER 15 バックアップ/リカバリの概要
* CHAPTER 16 バックアップの取得とファイル管理
* CHAPTER 17 障害復旧
* CHAPTER 18 論理バックアップ

* Part7 構成・設定管理
* CHAPTER 19 初期化パラメータの変更
* CHAPTER 20 構成ファイルの管理とパッチの適用
* CHAPTER 21 ネットワーク管理

* Part8 ログファイルの管理と障害対応
* CHAPTER 22 ログファイルの管理・分析
* CHAPTER 23 エラーと障害対応
* CHAPTER 24 セッション管理

### 執筆において留意した点
書籍「プロとしてのOracle運用管理入門」の執筆にあたっては、以下の点に留意しました。

* バージョンに依存しない、本質的で重要な機能を中心に記述
* 一般的に使用されることが少ない新機能については説明を割愛
* Standard Editionでも利用可能な機能に限定して解説
* Enterpise Editionでのみ使用できる機能、有償オプションの購入が必要な機能については説明を割愛
* 意外と適切で安全な構成がなされていないことが多い、バックアップ、アーカイブログ管理について見通しのよい解説とベストプラクティスを提供
* これまた意外と確実で適切な方法が知られていない実行計画の取得について、見通しのよい解説を提供
* 意外と知られていない便利な標準パッケージ、DBMS_XPLANパッケージを紹介(特にDBMS_XPLAN.DISPLAY_CURSORはオススメです!)

本書の記述内容はOracleのマニュアルに記載されているものがほとんどですが、
マニュアルの量は膨大で、状況に応じて必要な情報を得ることはほとんどの人にとって
難しいはずです。
DBAの方に、本書がお役に立てれば幸いです。