GAGA LIFE.

インフラエンジニアブログ

スポンサーリンク

Oracle アクセスパス

概要

Oracleのアクセス・パスについてまとめた内容を記載します。
アクセス・パスは、データを取り出す方法のことです。

アクセス・パス一覧

分類 実行計画(Operation) 説明
Table TABLE ACCESS FULL 全表走査。HWM(High Water Mark)までの全てのブロックにアクセスし、全行を取り出す。
単一のI/O呼び出しで複数のブロックが要求される。単一のI/Oでの読込みブロック数は最大でdb_file_multiblock_read_countパラメータの値。
TABLE ACCESS BY BY ROWID RANGE 指定された範囲のROWIDを使用してテーブルから行を取得。
TABLE ACCESS BY USER ROWID (ROWID を条件に指定した場合)ROWID を使用して表からの行を取得する。
TABLE ACCESS BY INDEX ROWID 索引からのROWIDを使用して表から行を取り出す。※索引は非パーティション
TABLE ACCESS BY GLOBAL INDEX ROWID 非ローカル・パーティション索引からのROWIDを使用して表から行を取り出す。
TABLE ACCESS BY LOCAL INDEX ROWID ローカルにパーティション化された索引からのROWIDを使用して表から行を取り出す。
TABLE ACCESS BY INDEX ROWID BATCHED 索引から取得したROWIDを同じデータ・ブロックごとにまとめてアクセスする。
TABLE ACCESS CLUSTER インデックスクラスタキーに基づいてクラスタ化されたテーブルの行にアクセスする。
TABLE ACCESS HASH ハッシュされたクラスタキーに基づいてクラスタ化されたテーブルの行にアクセスする
TABLE ACCESS SAMPLE テーブル内のブロックのサンプルをスキャンする。
テーブルデータをランダムにサンプルスキャンする。
TABLE ACCESS SAMPLE BY ROWID RANGE 指定されたROWID範囲を使用して、テーブル内のブロックのサンプルのスキャンする。
TABLE ACCESS INMEMORY FULL (インメモリ―列ストアが有効になっている場合)メモリ上のテーブルを全表走査する。
Index INDEX FULL SCAN 索引から全ての ROWID取得。表データをフルスキャンするのではなく、ソート済みの索引をフルスキャンするため、ソート処理を回避できる。
INDEX FULL SCAN (MIN/MAX) インデックス内の最初または最後のエントリを返却する。
最小値または最大値に相当する値を発見したところでリーフのスキャンを停止する。
INDEX FULL SCAN DESCENDING 降順で全索引スキャンする。
INDEX RANGE SCAN リーフ・ブロックをスキャンして条件に該当する複数エントリを返却する。
索引が定義された列に対して範囲条件(BETWEEN,<,>)を指定した場合と非一意索引の場合の等価条件でも選択される。
索引には索引列がソートして格納されているため、索引を使用してORDER BY句を満たせる場合はソート処理を回避可能。
INDEX RANGE SCAN DESCENDING INDEX RANGE SCAN を索引値の降順にスキャンする。
INDEX RANGE SCAN (MIN/MAX) インデックス範囲の最初または最後のエントリを返します。
最小値または最大値に相当する値を発見したところでリーフのスキャンを停止する。
INDEX SKIP SCAN 複合索引の第1列目に対する条件指定がなく、2列目以降の列に対して条件があった場合に
複合索引を使用して条件に該当する行を選択するアクセス方法
INDEX SKIP SCAN DESCENDING INDEX SKIP SCAN を索引値の降順にスキャンする。
INDEX UNIQUE SCAN 条件に該当する1エントリを返す。主キーor一意索引の付いた列に対して等価条件を使用している場合のみ選択される可能性がある。
INDEX FAST FULL SCAN INDEX FULL SCANのマルチブロックリード版。索引ブロックを先頭エクステントから格納順にアクセスする方法のため、戻される結果は索引キーの順にソートされていない。
INDEX SAMPLE FAST FULL SCAN 行のサンプルに対してインデックス高速フルスキャンを実行する。
HASH JOIN(INDEX JOIN) 索引が結合されている表から必要な列のみが索引に存在する列である場合にのみ可能。
AND-EQUAL 複数の ROWID のセットを受け取り重複をなくし共通する ROWID を戻す。
BITMAP INDEX SINGLE VALUE 単一のキー値のビットマップ内の行を返す。
BITMAP INDEX RANGE SCAN 一連のキー値のビットマップ内の行を返す。
BITMAP INDEX FULL SCAN 可能なすべてのキー値のビットマップ内の行を返す。
BITMAP INDEX FAST FULL SCAN 可能なすべてのキー値のビットマップ内の行を返す。
BITMAP CONSTRUCTION ビットマップインデックスの作成時にビットマップを構築する。
BITMAP COMPACTION ビットマップインデックスの作成中にビットマップを圧縮する。
BITMAP CONVERSION FROM ROWIDS ROWIDのセットをビットマップのセットに変換する。
BITMAP CONVERSION TO ROWIDS ビットマップをキー値に変換し、ROWIDに変換する。
BITMAP AND WHERE句に複数の条件をANDで指定した場合、いくつかのビットマップ索引のビットマップ・エントリをマージする
BITMAP OR 複数の条件をORて指定した場合に実行される。
BITMAP MINUS 特定のビットマップからほかのビットマップで1が立っているビットを排除する処理
BITMAP MERGE BITMAP AND/OR/MINUSなどのオペレーションを実行する前に、RANGE SCANの結果得られた複数のビットマップをマージ
BITMAP CONVERSION COUNT 1つまたは複数のビットマップの行数のカウントを返します。
BITMAP KEY ITERATION ビットマップを反復処理します。スター・トランザクションで使用

参考資料

Expert Oracle SQL 

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

 

Pro Oracle SQL, Second Edition 

Pro Oracle SQL (Expert's Voice in Oracle)

Pro Oracle SQL (Expert's Voice in Oracle)

  • 作者: Karen Morton,Kerry Osborne,Robyn Sands,Riyaj Shamsudeen,Jared Still
  • 出版社/メーカー: Apress
  • 発売日: 2013/10/29
  • メディア: ペーパーバック
  • この商品を含むブログを見る
 

Troubleshooting Oracle Performance, Second Edition 

Troubleshooting Oracle Performance

Troubleshooting Oracle Performance

 

Expert Oracle Indexing and Access Paths: Maximum Performance for Your Database

Expert Oracle Indexing and Access Paths: Maximum Performance for Your Database

Expert Oracle Indexing and Access Paths: Maximum Performance for Your Database

 

https://docs.oracle.com/cd/E82638_01/TGSQL/optimizer-access-paths.htm#GUID-00711237-35D3-4CFC-A234-59B3EC53DCD1
8 オプティマイザのアクセス・パス

Oracle 実行計画の確認方法(DBMS_XPLAN.DISPLAY_CURSOR)

概要

SQLパフォーマンス調査で使用するDBMS_XPLANについてのまとめを記載します。

DBMS_XPLAN.DISPLAY_CURSORについて:
過去にDatabaseで実行されたSQLの実行計画を確認することが可能です。

また、この機能を使用することでSQL文の実行計画とそのSQLを実行した際の実行統計の情報を併記して表示することが可能です。
そのため、この機能によって、CBO(コストベース・オプティマイザ)の見積もりミスの有無やメモリ不足等の事象で作業効率が悪くなっていないかを確認したりすることが可能になります。

特徴

  • 過去に実行されたSQL文の共有カーソルの情報がライブラリ・キャッシュに存在している場合に該当SQLの実行計画を確認することが可能です。
    → ライブラリ・キャッシュからage-outされていた場合は確認することが出来ません。
  • 既に実行されキャッシュされている情報を検索するため、実行計画を確認するためにSQL文を再度解析する必要がなく、低コストで実行できます。
  • 実行計画と併せて実行統計も表示することが可能なため、Estimate(見積)とActual(実測)の乖離の確認が容易です。

使用の前提条件

DISPLAY_CURSOR機能を使用する場合、ユーザーに下記ビューに対するSELECTまたはREAD権限が必要です。
権限がない場合は、エラー・メッセージが表示されます。
※DBMS_XPLANは内部的にこれらのビューに対する検索を実行し、情報を表示しています。

  • V$SQL_PLAN_STATISTICS_ALL
  • V$SQL
  • V$SQL_PLAN

パラメータ

DISPLAY_CURSORファンクションのパラメータは下記です。
   sql_id:カーソル・キャッシュ内のSQL文のSQL_IDを指定します。
              NULLの場合、セッションで最後に実行されたカーソルが表示されます。
   cursor_child_no:表示するカーソルの子番号を指定します
                              ※NULLの場合、指定のsql_idパラメータに一致するすべてのカーソルの実行計画を表示
   format:計画の詳細レベルを制御します。

format句の指定

BASIC:計画の最小限の情報として、操作ID、操作名および操作オプションを表示します。
TYPICAL:これがデフォルトです。計画に関する最も一般的な情報
                 (操作ID、操作名、操作オプション、行数、バイト数およびオプティマイザ・コスト)が表示されます。
SERIAL:TYPICALと同じですが、計画がパラレルで実行される場合でもパラレル情報は表示されません。
ALL:TYPICALレベルで表示される情報に加えて、
         追加情報(PROJECTION、ALIAS、および分散処理が行われる場合はREMOTE SQLに関する情報)が表示されます。

ADVANCEDパラメータについて

マニュアルには記載がありませんが、上記以外にformat句に「ADVANCED」を指定することが可能です。
このオプションによって、OUTLINE(ヒント句)の情報などの追加情報が表示できます。

formatパラメータで指定可能な修飾子
Value Description
adaptive サブプランの表示を制御します。この修飾子は、バージョン12.1以降でのみ使用できます。
alias クエリブロック名とオブジェクトエイリアスを含むセクションの表示を制御します。
bytes 実行計画テーブルのバイト列の表示を制御します。
cost 実行計画テーブルのCost列の表示を制御します。
note ノートを含むセクションの表示を制御します。
outline アウトラインを含むセクションの表示を制御します。
parallel 並列処理情報、具体的には実行計画表のTQ、IN-OUT、およびPQ Distrib列の表示を制御します。
partition パーティション化情報、特に実行計画テーブルのPstart列とPstop列の表示を制御します。
peeked_binds 表示されたバインド変数を含むセクションの表示を制御します。
predicate フィルター、アクセス、およびストレージの述部を含むセクションの表示を制御します。
projection 列投影情報を含むセクションの表示を制御します。
remote リモートで実行されるSQL文の表示を制御します。
report レポートモードのアクティブ化を制御します。
有効にすると、適応および再最適化された実行計画に関する追加情報が表示されます。
この修飾子は、バージョン12.1以降でのみ使用できます。
rows 実行計画テーブルの行列の表示を制御します。

format句に指定可能なパラメータの詳細については以下のマニュアルを参考にしてください。

https://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_xplan.htm#sthref14602

Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 11g リリース2(11.2)
https://docs.oracle.com/cd/E57425_01/121/ARPLS/d_xplan.htm#i998364

https://docs.oracle.com/cd/E57425_01/121/ARPLS/d_xplan.htm#i998364
Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース1 (12.1)

https://docs.oracle.com/cd/E82638_01/ARPLS/DBMS_XPLAN.htm#GUID-BAD480AA-351A-48FE-A8E7-F0D8EF643EBF
  Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース2 (12.2)

  詳細については「$ORACLE_HOME/rdbms/admin/dbmsxpln.sql」でも確認できます。

また、すべてのレベルは、データを削除するマイナス記号または追加するオプションのプラス記号とともに、詳細な制御を使用してカスタマイズできます。
例) 「ADVANCED -COST」や「BASIC +PEEKED_BINDS」

実行統計を併記する方法

実行統計の収集するには、SQL文の実行時に実行統計を取得する必要がありますが、SQL実行統計を収集する場合は、以下の3つの条件のいずれかを満たしている必要があります。

  • STATISTICS_LEVELパラメータをALLの状態でSQL文を実行する
  • SQL文にGATHER_PLAN_STATISTICSヒントを指定して実行する
  • SQLトレースを有効にしてSQL文を実行する

上記にて統計情報が収集されている場合には、DBMS_XPLAN.DISPLAY_CURSORにてformat句に以下のキーワードを指定します。

  IOSTATS : I/Oに関する実行統計を表示
  MEMSTATS : メモリに関する実行統計を表示
  ALLSTATS : IOSTATSとMEMSTATSの両方を指定
  LAST : このオプションが指定されていると特定のSQL文を最後に実行した際の1回分の統計を表示。
              指定しない場合は同一SQL文の全実行を集計表示。
              (注:パラレルクエリの場合にLASTを指定する場合は注意してください。Doc ID 1757657.1参照)

format句の書式レベルと制御
パラメータ alias bytes cost note predicate parallel partition projection outlines peeked_binds remote rows
Column/Section S C C S S C C S S S S C
BASIC                        
null              
TYPICAL        
SERIAL            
ALL  
ADVANCED

現時点で、DBMS_XPLAN.DISPLAY_CURSORから最大の表示を得るには、formatパラメータに 'ADVANCED ALLSTATS LAST ADAPTIVE'を指定する必要があります。

表示内容

表示される実行計画の各ステップには、次のような項目が併記されます。
※SQLの実行内容とformat句で指定したパラメータに応じて下記項目から必要な情報が表示されます。
なお、この情報は、V$SQL_PLAN_STATISTICS_ALLから取得しています。

▽実行計画を含むテーブルの列
Column Description
Basics(Always Available)
id 実行計画内の各操作(行)の識別子。番号の前にアスタリスクが付いている場合は、その行の述部情報が後で使用できることを意味します。
Operation 実行される操作。これは、行ソース操作とも呼ばれます。
Name 操作が実行されるオブジェクト。
Query Optimizer Estimations
Rows and E-Rows 操作によって戻された推定行数。
Bytes and E-Bytes 操作によって戻されたデータの見積もり量。
TempSpc and E-Temp 操作に必要な一時スペースの推定量(バイト単位)。
Cost (%CPU) 操作の推定コスト。 CPUコストの割合はカッコで示しています。この値は実行計画によって累積されます。
つまり、親オペレーションのコストには、子オペレーションのコストが含まれています。
Time and E-Time 操作を実行するのに必要な推定時間(HH:MM:SS)。
Partitioning
Pstart アクセスされる最初のパーティションの番号。その番号が解析時にわからない場合は、KEYまたはINVALIDのいずれかです。
KEYは、実行フェーズ中に最初のパーティションが決定されたときに使用されます。
Pstop アクセスされる最後のパーティションの番号。その番号が解析時にわからない場合は、KEYまたはINVALIDのいずれかです。
KEYは、実行フェーズ中に最後のパーティションが決定されたときに使用されます。
Parallel and Distributed Processing
Inst 分散処理の場合、操作で使用されるデータベース・リンクの名前。
TQ 並列処理の場合、スレーブプロセス間の通信に使用されるテーブルキュー。
IN-OUT 並列または分散操作の関係。
PQ Distrib 並列処理の場合、プロデューサがデータをコンシューマに送信するために使用されるディストリビューション。
Runtime Statistics*
Starts 特定の操作が実行された回数。特別な場合には、この統計情報は、特定のメモリ構造にアクセスした回数を示します
A-Rows 操作によって戻される実際の行数。
A-Time 操作の実行に費やされた実際の時間(HH:MM:SS.FF)。
I/O Statistics*
Buffers 実行中に実行された論理読み取りの数。
Reads 実行中に実行された物理読み込みの数。
Writes 実行中に実行された物理書き込みの数。
Memory Utilization Statistics
Omem 最適な実行に必要なメモリーの推定量(バイト単位)。
1Mem 1パス実行に必要なメモリーの推定量(バイト単位)。
O/1/M(*2) 実行が最適/ワンパス/マルチパスモードで実行された回数。
Used-Mem(*1) 最後の実行中に操作で使用されたメモリー量(バイト単位)。
Used-Tmp(*1) 最後の実行中に操作で使用された一時スペースの量(キロバイト単位)。他のメモリー使用率列と一致するように、この値に1,024を掛けなければなりません(たとえば、32Kは32MBを意味します)。
Max-Tmp(*2) 操作で使用される一時スペースの最大量(キロバイト単位)。この値は、他のメモリ使用率列と一致するように、1,024を掛けなければなりません(たとえば、32Kは32MBを意味します)。

  *実行統計が有効になっている場合に出力される項目

  赤字:Estimate  青字:Actual(実行統計)

  (*1)format句にLAST指定をした場合に表示される項目
  (*2)format句にLAST指定をしなかった場合に表示される項目

  (補足)
  Optimal:そのステップ(例えばSORT)のすべての作業をメモリ内で実行すること
  1-pass:中間データを一段階ディスクに退避してマージ作業を行うこと
  Multi-pass:中間データを二段階以上ディスクに退避してマージ作業を行うこと

▽セクションの表示内容(実行計画以外の部分)

1.
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
  1 - SEL$1
  3 - SEL$1 / T2@SEL$1
  4 - SEL$1 / T2@SEL$1
  5 - SEL$1 / T1@SEL$1

このセクションでは、クエリブロック名とオブジェクトエイリアスを示します。
実行計画の各操作では、関連するクエリブロックと、オプションで実行されるオブジェクトが表示されます。
この情報は、SQL文が同じ表を複数回参照する場合には不可欠です。

2.
Outline Data
-------------
/*+
     BEGIN_OUTLINE_DATA
     IGNORE_OPTIM_EMBEDDED_HINTS
     OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
     DB_VERSION('11.2.0.4')
     ALL_ROWS
     OUTLINE_LEAF(@"SEL$1")
     INDEX_RS_ASC(@"SEL$1" "T2"@"SEL$1" ("T2"."ID"))
     FULL(@"SEL$1" "T1"@"SEL$1")
     LEADING(@"SEL$1" "T2"@"SEL$1" "T1"@"SEL$1")
     USE_HASH(@"SEL$1" "T1"@"SEL$1")
     END_OUTLINE_DATA
*/

その特定の実行計画を再現するのに十分な、アウトラインと呼ばれる一連のヒントを示します。
アウトラインには必ずしもすべての必要なヒントが含まれているとは限りません。

3.
Peeked Binds (identified by position):
--------------------------------------
   1 - :T1_ID (NUMBER): 6
   2 - :T2_ID_MIN (NUMBER): 6
   3 - :T2_ID_MAX (NUMBER): 19

問合せオプティマイザがバインド変数を利用する場合にのみ表示されます。
上記の通り、各バインド変数のデータ型と値が表示されます。

4.
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(:T2_ID_MIN<=:T2_ID_MAX)
   2 - access("T1"."N"="T2"."N")
   4 - access("T2"."ID">=:T2_ID_MIN AND "T2"."ID"<=:T2_ID_MAX)
   5 - filter("T1"."ID">:T1_ID)

どの述部が適用されるかを示します。
それぞれについて、(行)と方法(アクセス、フィルタまたはストレージ)が適用される場所が示されます。
アクセス述語は、効率的なアクセス構造を利用して行を特定するために使用されますが、フィルタ述語は行をすでに格納している構造体から抽出されています。

5.
Column Projection Information (identified by operation id):
-----------------------------------------------------------
   1 - "T2"."N"[NUMBER,22], "T2"."ID"[NUMBER,22], "T2"."PAD"[VARCHAR2,1000]
   2 - (#keys=1) "T2"."N"[NUMBER,22], "T2"."ID"[NUMBER,22],"T2"."PAD"[VARCHAR2,1000]
   3 - "T2"."ID"[NUMBER,22], "T2"."N"[NUMBER,22], "T2"."PAD"[VARCHAR2,1000]
   4 - "T2".ROWID[ROWID,10], "T2"."ID"[NUMBER,22]
   5 - "T1"."N"[NUMBER,22]

各操作が実行されるときにどの列が出力として返されるかを示します。

6.
Note
-----
   - dynamic sampling used for this statement (level=2)

最後に、最適化フェーズ、環境、またはSQLステートメント自体に関する注釈と警告を提供するセクションがあります。
上記例では、問合せオプティマイザがオブジェクト統計を収集するために動的サンプリングを使用したことが通知されます。

実行例

SQL> set linesize 200
SQL> col sql_id for a15
SQL> select sql_id,sql_text from v$sqltext where sql_text like 'select * from emp%';
SQL_ID          SQL_TEXT
--------------- ----------------------------------------------------------------
8wqqr7cg11y7t   select * from emp e, dept d where e.deptno = d.deptno
SQL> set line 2000
SQL> set pages 2000
SQL> alter session set nls_date_format = 'yyyy/mm/dd hh24:mi:ss';
Session altered.
SQL> select * from table(dbms_xplan.display_cursor('&SQLID',null,'advanced'));
Enter value for sqlid: 8wqqr7cg11y7t
old 1: select * from table(dbms_xplan.display_cursor('&SQLID',null,'advanced'))
new 1: select * from table(dbms_xplan.display_cursor('8wqqr7cg11y7t',null,'advanced'))
SQL_ID 8wqqr7cg11y7t, child number 1
-------------------------------------
select * from emp e, dept d where e.deptno = d.deptno
Plan hash value: 615168685
---------------------------------------------------------------------------
| Id | Operation        | Name | Rows | Bytes | Cost (%CPU)| Time         |
---------------------------------------------------------------------------
|  0 | SELECT STATEMENT |      |      |       |     6 (100)|              |
|* 1 | HASH JOIN        |      |   14 |  1638 |     6   (0)|     00:00:01 |
|  2 | TABLE ACCESS FULL| DEPT |    4 |   120 |     3   (0)|     00:00:01 |
|  3 | TABLE ACCESS FULL| EMP  |   14 |  1218 |     3   (0)|     00:00:01 |
---------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1
   2 - SEL$1 / D@SEL$1
   3 - SEL$1 / E@SEL$1
Outline Data
-------------
  /*+
       BEGIN_OUTLINE_DATA
       IGNORE_OPTIM_EMBEDDED_HINTS
       OPTIMIZER_FEATURES_ENABLE('12.2.0.1')
       DB_VERSION('12.2.0.1')
       ALL_ROWS
       OUTLINE_LEAF(@"SEL$1")
       FULL(@"SEL$1" "D"@"SEL$1")
       FULL(@"SEL$1" "E"@"SEL$1")
       LEADING(@"SEL$1" "D"@"SEL$1" "E"@"SEL$1")
       USE_HASH(@"SEL$1" "E"@"SEL$1")
       END_OUTLINE_DATA
   */
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("E"."DEPTNO"="D"."DEPTNO")
Column Projection Information (identified by operation id):
-----------------------------------------------------------
   1 - (#keys=1) "D"."DEPTNO"[NUMBER,22], "E"."DEPTNO"[NUMBER,22],
       "D"."LOC"[VARCHAR2,13], "D"."DNAME"[VARCHAR2,14],
       "E"."EMPNO"[NUMBER,22], "E"."ENAME"[VARCHAR2,10],
       "E"."JOB"[VARCHAR2,9], "E"."MGR"[NUMBER,22], "E"."HIREDATE"[DATE,7],
       "E"."SAL"[NUMBER,22], "E"."COMM"[NUMBER,22]
   2 - (rowset=256) "D"."DEPTNO"[NUMBER,22], "D"."DNAME"[VARCHAR2,14],
       "D"."LOC"[VARCHAR2,13]
   3 - (rowset=256) "E"."EMPNO"[NUMBER,22], "E"."ENAME"[VARCHAR2,10],
       "E"."JOB"[VARCHAR2,9], "E"."MGR"[NUMBER,22], "E"."HIREDATE"[DATE,7],
       "E"."SAL"[NUMBER,22], "E"."COMM"[NUMBER,22], "E"."DEPTNO"[NUMBER,22]
Note
-----
    - dynamic statistics used: dynamic sampling (level=2)

124 rows selected.

※12cR2からtable句の省略可

(これまで) select * from table(dbms_xplan.display_cursor('&SQLID',null,'allstats last'));

(12.2以降) select * from (dbms_xplan.display_cursor('&SQLID',null,'allstats last'));

個人的希望

個人的には以下のサイトのQ&Aにもある通り、「-SQLTEXT」「-QUERY」のようなオプションを設けてPLANから確認が始められる(SQLテキスト部分を除外できる)ようにして欲しい。

https://sqlmaria.com/2017/08/08/using-dbms_xplan-display_cursor-to-examine-execution-plans/

参考資料

Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

 

Troubleshooting Oracle Performance, Second Edition

Troubleshooting Oracle Performance

Troubleshooting Oracle Performance

 

https://docs.oracle.com/cd/E82638_01/TGSQL/reading-execution-plans.htm#GUID-725CADF8-3803-416F-96EB-BF942F742663
Oracle® Database SQLチューニング・ガイド 12cリリース2 (12.2)

https://sqlmaria.com/2017/08/08/using-dbms_xplan-display_cursor-to-examine-execution-plans/

Oracle 実行計画の取得方法の選択について

概要

Oracleで実行計画を取得する方法をまとめました。
※普段は、SQLチューニング依頼を受けた場合にはDBMS_XPLAN.DISPLAY_CURSORを使用しています。

方法

  1. EXPLAIN PLAN+DBMS_XPLAN
  2. AUTOTRACE(SQL*Plus)
  3. DBMS_XPLANパッケージ(CURSOR/AWR)
  4. 動的パフォーマンスビュー(V$SQL_PLAN/V$SQL/V$SQL_TEXT)
  5. SQLトレース+tkprof
  6. リアルタイムSQL監視

上記5にはさらに以下があります。

  • SQL_TRACE(11gR1-)
  • 10046トレース
  • DBMS_MONITOR

取得方法まとめ

方法 取得工数(手間) システム負荷 実行統計 Actual値の取得 ライセンス要否
EXPLAIN PLAN × Estimate 不要
AUTOTRACE Actual 不要
DBMS_XPLAN Actual 要(※Diagnostic Packライセンス)
V$ビュー × Actual 不要
SQLトレース SQL_TRACE(11gR1-) Actual 不要
EVENT10046 Actual 不要
DBMS_MONITOR Actual 要(※Tuning Packライセンス)
リアルタイムSQL監視 Actual 要(※Tuning Packライセンス)

補足

Actual(実行):
   過去、SQL実行で実際に使用された実行計画・実行統計を表示
Estimate(見積):
   Oracleが予測で見積もった実行計画・実行統計を表示。
   そのため、実行時の実行計画と異なる可能性あり

なお、DBMS_XPLANは、利用方法によってEstimate/Actualが異なります。

  パターン1.EXPLAINとの併用 実行計画:Estimate/実行統計:Actual
  パターン2.SQL実行後の取得 実行計画:Actual/実行統計:Estimate
  パターン3.STATISTICS_LEVEL=ALL+format句にALLSTATS LAST
                  実行計画:Actual/実行統計:Estimate&Actual

その他の取得方法

  • STASPACK/AWR SQLレポート
  • SQLHC
  • SQLTXPLAIN(SQLT)
  • EVENT10053→※CBOトレースですが、実行計画情報も含まれます

        ...他多数

メリット/デメリット

No 取得方法 メリット/デメリット
1 EXPLAIN+DBMS_XPLAN <メリット>
  • SQLを実行しない(PARSEのみ)ため、PLANを即時に確認可能
  • Client側(SQL*Plus等)のみで作業が完結可能
  • PLANの詳細情報の確認可能(パラレル・クエリ等)
  • バインド変数を設定しなくてもPLANの確認が可能
  • DMLであっても実行せずにPLANの取得可

<デメリット>

  • EXPLAINで確認したPLANと実行時のPLANに差異がある場合がある
2 AUTOTRACE <メリット>
  • PLANの取得と実行統計の取得がSQL*PLUSのみで完結するため取得工数が少ない
<デメリット>
  • PLANの確認は、SQL完了まで待つ必要がある
  • SQL*Plusでのみの使用となる
  • PLANの出力は、内部的にはEXPLAIN PLANが実行されているため実行時のPLANと異なる場合がある
  • 「SET AUTOTRACE TRACEONLY」を実行しても(あくまでSQL*Plusの表示上の範囲のため)SQLが実行されてしまう
3 DBMS_XPLAN <メリット>
  • EstimateとActualの双方が取得可能(format句による)
  • 事前設定が少ないため、比較的に簡易に取得可能
  • 「Predicate Information」等の追加情報が得られる

<デメリット>

  • CURSORの場合、共有プール上に存在しない場合、情報が取得できない
4 V$ビュー <メリット>
  • (権限が付与されていれば)簡易に取れるため、取得工数が少ない
<デメリット>
  • 実行統計は取得できない
5 SQLトレース <メリット>
  • 出力されるPLANが実行時のPLAN(Estimateではない)
  • PLANと併せて実行統計(経過時間/ブロック読込量/待機イベント)も取得可能

<デメリット>

  • PLANの出力は、SQLが完了するまで待つ必要がある
  • SQLコマンドとOSコマンド(tkprof)が混在するため手順が増える
6 リアルタイムSQL監視 <メリット>
  • 取得に伴うオーバーヘッドが少ない
  • GUIから容易にボトルネックとなっている処理が特定できる
  • SQLの終了待たず、実行中にPLANや実行統計が確認可能

<デメリット>

  • (MONITORヒント)を付与していない場合、5秒以内のSQLは監視にかからない

参考資料

--V$ビュー

http://odakeiji.blog33.fc2.com/blog-entry-23.html

--リアルタイムSQL監視

http://www.oracle.com/technetwork/jp/ondemand/db-basic/d-16-ssqltuning-1448439-ja.pdf

--その他
Oracle SQL Tuning with Oracle SQLTXPLAIN: Oracle Database 12c Edition

Oracle SQL Tuning with Oracle SQLTXPLAIN: Oracle Database 12c Edition

Oracle SQL Tuning with Oracle SQLTXPLAIN: Oracle Database 12c Edition

 

--全体
Expert Oracle SQL 

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

 

Cost-Based Oracle Fundamentals 

Cost-Based Oracle Fundamentals (Expert's Voice in Oracle)

Cost-Based Oracle Fundamentals (Expert's Voice in Oracle)

 

Pro Oracle SQL, Second Edition 

Pro Oracle SQL (Expert's Voice in Oracle)

Pro Oracle SQL (Expert's Voice in Oracle)

  • 作者: Karen Morton,Kerry Osborne,Robyn Sands,Riyaj Shamsudeen,Jared Still
  • 出版社/メーカー: Apress
  • 発売日: 2013/10/29
  • メディア: ペーパーバック
  • この商品を含むブログを見る
 

Troubleshooting Oracle Performance, Second Edition 

Troubleshooting Oracle Performance

Troubleshooting Oracle Performance

 

Oracle® Database SQLチューニング・ガイド 12cリリース2 (12.2)

http://www.doppo1.net/oracle/tuning/explain-plan.html#2

https://www.ashisuto.co.jp/db_blog/article/20160630_sqltrace.html

http://d.hatena.ne.jp/yohei-a/20160605/1465079548

http://www.intellilink.co.jp/article/column/ora-report20150507.html

Oracle 統計情報の収集(DBMS_STATSの各プロシージャのパラメータ)

概要

統計情報の収集のために、DBMS_STATSパッケージにはいくつかのプロシージャが用意されていますが、それぞれの特徴やパラメータについてまとめます。

各プロシージャについて

システム特性や取得対象に応じてデータベース全体/データディクショナリ/スキーマ/単一オブジェクトに対して統計情報を収集するプロセスが発生する必要があり、いくつかのプロシージャがあります。

プロシージャ 説明
gather_database_stats データベース全体のオブジェクト統計を収集
gather_dictionary_stats データディクショナリの統計を収集
データディクショナリは、sysスキーマに格納されているオブジェクトで構成されているだけでなく、オプションのコンポーネント用にOracleによってインストールされた他のスキーマも含みます。
gather_fixed_objects_stats 固定表(X$表)とデータディクショナリの一部である特定のオブジェクトの統計を収集
動的パフォーマンスビューでよく使用される固定表メモリ構造のみです。
どの表がこのプロシージャに関連しているかを知るには、v$fixed_tableを確認することで確認可能です。
※ただし、固定されたテーブルごとにオブジェクト統計が収集されるわけではない
gather_table_stats スキーマ全体のオブジェクト統計を収集
gather_table_stats 列を含む1つの表、およびオプションで索引のオブジェクト統計を収集
gather_index_stats 1つの索引のオブジェクト統計を収集

Note:
統計情報の収集は、DBMS_STATSパッケージの使用以外にも動作しています。
例えば、CREATE INDEXおよびALTER INDEX文は、索引作成の際に統計情報を自動的に収集します。
さらに、12.1以降では、CTAS文と空テーブルへのDIRECT PATH INSERTにより、統計が自動的に収集されます。
※DBMS_STATSパッケージによる統計の計算は、自動的に収集されたものより優れている可能性があることに注意

各パラメータの範囲と使用方法

  • DBMS_STATSパッケージによって提供されるプロシージャには、3つの主要なカテゴリに
    グループ化できるいくつかのパラメータがあります。
    • 第1グループ:ターゲットオブジェクトの指定
    • 第2グループ:収集オプションの指定
    • 第3グループ:現在の統計を上書きする前にバックアップするか否かの指定

統計収集に使用されるプロシージャのパラメータ

Parameter Database Dictionary Fixed Objects Schema Table Index
Taget Objects
ownname
indname
tabname
partname
comp_id
granularity
cascade
gather_fixed
gather_sys
gather_temp
options ✓*
objlist
force
obj_filter_list
Gathering Options
estimate_percent
block_sample
method_opt
degree
no_invalidate
Backup Table
stattab
statid
statown

✓*12.1から利用可能

参考資料


Troubleshooting Oracle Performance, Second Edition

Troubleshooting Oracle Performance

Troubleshooting Oracle Performance


Oracle® Database PL/SQLパッケージおよびタイプ・リファレンス 12c リリース2 (12.2)

Oracle オブジェクト統計

概要

統計情報の管理や、統計情報の不備による実行計画変化で性能劣化を招いた場合の対処として、オブジェクト統計に関する知識は必須なため、 その知識習得のキッカケとして種類や確認するビューなどを記載します。

  • オブジェクト統計には、下記の3種類があります。
    • 表統計
    • 列統計
    • 索引統計
  • さらに各タイプには、下記の3つのタイプがあります。
    • 表/索引レベルの統計
    • パーティション・レベルの統計
    • サブパーティション・レベルの統計 パーティションとサブパーティションの統計は、オブジェクトがそれぞれ分割され、サブパーティション化されている場合にのみ存在します。

オブジェクト統計は、下記の表のようなデータ・ディクショナリ・ビューに表示されます。
各ビューには、dba_all_、がそれぞれ存在しています。
また、12.1マルチテナント環境では、dba_tab_statistics/all_tab_statistics/cdb_tab_statistics等のcdbバージョンもあります。

オブジェクト統計に関するデータ・ディクショナリ・ビュー

Object Table/Index-Level Statistics Partition-Level Statistics Subpartition-Level Statistics
Tables user_tab_statistics user_tab_statistics user_tab_statistics
Indexes user_ind_statistics user_ind_statistics user_ind_statistics
Columns user_tab_col_statistics
user_tab_histgrams
user_part_col_statistics
user_part_histgrams
user_subpart_col_statistics
user_subpart_histgrams

参考資料

Troubleshooting Oracle Performance, Second Edition

Troubleshooting Oracle Performance

Troubleshooting Oracle Performance


Oracle® Databaseリファレンス 12cリリース2 (12.2)
https://docs.oracle.com/cd/E82638_01/REFRN/toc.htm

Oracle 統計情報の種類

概要

Oracleの統計情報について簡単にまとめます。
これらの精度を高めることがよりよい実行計画を生成する可能性を高めることにつながります。

Oracleの統計情報の種類とそれぞれの特徴

種類 概要 未取得時の影響 取得方法
オブジェクト統計 表統計 表に対する統計
  • 表(パーティション)の行数
  • 表内に格納されたHWM以下に存在するデータブロック数
  • 表内の行の長さの平均
  • 行連鎖/行移行が発生している行数 など
非効率な実行計画が生成される可能性がある DBMS_STATS.GATHER_TABLE_STATS
索引統計 索引に対する統計
  • ルート・ブロックからリーフ・ブロックまでの索引の高さ
  • 索引に含まれるリーフ・ブロックの数
  • クラスタ化係数
  • 索引キー値の種類の数 など
同上 DBMS_STATS.GATHER_INDEX_STATS
列統計 列に対する統計
  • 列内に含まれる値の種類
  • 値がNULLの行数
  • 列の最小値/最大値
  • 列内に格納されたデータの分布度 など
同上

DBMS_STATS.GATHER_TABLE_STATS

※method_opt引数で制御

システム統計 システムのI/O性能やCPU速度の統計情報
※NOWORKLOAD統計/WORKLOAD統計がある
サーバーのリソース状況に合った実行計画が生成されない可能性がある DBMS_STATS.GATHER_SYSTEM_STATS();
ディクショナリ統計 データディクショナリの統計情報
  • 再帰的SQLやユーザSQLのハードパース時に長時間化する可能性がある
  • バックグラウンドプロセスの内部SQL/EM/AWRなどが発行するSQLで不適切な実行計画が選択される可能性がある
DBMS_STATS.GATHER_DICTIONARY_STATS();
固定オブジェクト統計 V$ビューなどの動的パフォーマンスビューのもととなるX$表などの固定オブジェクトの統計情報 同上 DBMS_STATS.GATHER_FIXED_OBJECTS_STATS();

参考資料

Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

 

Oracle 結合方法と結合タイプ

はじめに

Oracleの結合方法/結合タイプについて記載します。

結合アルゴリズム

結合アルゴリズム 日本語 ヒント句
Nested Loops Joins ネステッド・ループ結合 USE_NL/NO_USE_NL/USE_NL_WITH_INDEX
Hash Joins ハッシュ結合 USE_HASH/NO_USE_HASH
Sort Merge Joins ソートマージ結合 USE_MERGE/NO_USE_MERGE
Merge Join Cartesian デカルト結合(直積)  

結合タイプ

結合タイプ 日本語 Nested Loops Joins Hash Joins Sort Merge Joins
Cross Join クロス結合  
Semi/anti-join セミ/アンチ結合
Outer join 外部結合  
inner join(theta Join) 内部結合  
Equi-join 等価結合
Band join バンド結合    

各結合アルゴリズムの概要

Nested Loops Joins(ネステッド・ループ結合)

f:id:undercovergeek:20180605223857j:plain

▽動作

  • ループ処理をネスト(入れ子構造)にして結合処理を実行
  • 外部ループで参照される表=外部表。内部ループで参照される表=内部表
  • 外部表の返却行数分、内部表に対するループ処理が発生するため、外部表は駆動表とも呼ばれる
  • はじめに外部表にアクセスする
  • 外部表から戻された行数分、内部表にアクセスし、条件に合致するデータを返却する

▽特徴

  • カーディナリティが小さい表を外部表とする
  • 外部表のカーディナリティが内部表の参照回数となる
  • 実レコード件数ではなくカーディナリティが小さい表を外部表とする
  • 内部表のアクセス効率を上げる
  • 内部表の結合列に索引があると効率的

▽パフォーマンス

  • 処理回数のみを考慮した場合、外部表から返される行数が少なれければ内部表に対するループ回数が減るため、条件指定で返却行数が少ない表を外部表に指定する(カーディナリティが小さい表を外部表に指定する)
  • 外部表からの返却行数が少ない場合でも内部表を全件検索せざるを得ない場合はパフォーマンスが悪い
  • 内部表に対する絞込み条件と外部表との結合条件で索引が効率的に使用されているか等、内部表に対するアクセス方法を考慮する必要がある
Hash Joins(ハッシュ結合)

f:id:undercovergeek:20180605223853j:plain

▽動作

  • 表1から抽出条件に合致する結果セットを返却
  • 結果セットの結合キーを基にハッシュ表をPGA内に作成
  • 表2から絞込み条件に合致する結果セットを返す
  • 結果セットの結合キーを順にハッシュし、ハッシュ表と照合し結合条件に合致する行を特定

▽特徴

  •  カーディナリティが小さい方を先に処理する(PGAに作成)
  • PGA上に作成される表が小さくなるため、結合処理が効率的
  • 一時表領域へのI/Oが発生する可能性がある
  • ハッシュ表がメモリ内に収まらない場合には一時表領域を使用するためディスクI/Oの発生により性能が劣化する可能性がある
    ⇒PGA_AGGREGATE_TARGETまたはHASH_AREA_SIZEを考慮する
  • 等価条件でのみ使用される
  • 結合条件が等価結合でない(範囲指定)場合、ハッシュ結合は使用されない
  • アクセス方法はフルスキャン
  • 必ず表のフルスキャン、または索引フルスキャン

▽パフォーマンス 

   ・一方の表から結合キーをもとにメモリ内(PGA)にハッシュテーブルを構築した際、ハッシュテーブルがPGA内で収まりきれない場合、一時表領域(TEMPファイル)を使用して他方の表と結合処理が行われる。そのため、他方の結合キーによっては、TEMPファイルに対するディスクI/Oが発生するのでその分がオーバヘッドになる

Sort Merge Joins(ソート・マージ結合)

f:id:undercovergeek:20180605223900j:plain

▽動作

  • 表1の結果セットを結合列でPGA内でソート
  • 表2の結果セットを結合列でPGA内でソート
  • ソート処理はシリアル実行
  • ソート結果をPGA内でマージして結果を返却

▽特徴

  • 一時表領域(Tempファイル)へのI/Oが発生する可能性がある
  • ソート処理がメモリ内に収まらない場合、一時表領域を使うためディスクI/Oの発生し、性能劣化が発生する可能性がある
    ⇒PGA_AGGREGATE_TARGETまたはSORT_AREA_SIZEを考慮する
  • 表1は一定条件でソート処理が回避できる(表2のソートは回避できない)
  • 表1は、結合列に索引が定義され、かつNOT NULL制約が存在する場合、索引フルスキャンを実行することでソート処理を回避可能
  • 表2は、ソートを実行しながら結合を進めるため、ソート処理は回避できない

▽パフォーマンス

  • 各表の結合キーがソートされてPGA内に保持されるため、ソートに必要な領域がPGA内で収まりきれない場合、一時表領域のTEMPファイルが使用される。ソートされた結合キー同士をマージするときに、ディスクI/Oが発生し、その分がオーバヘッドとなる
Merge Join Cartesian(デカルト積)

f:id:undercovergeek:20180605223903j:plain

▽動作

  • 結果セット1の全行と結果セット2の全行を直積(掛け算)
  • 3表以上の結合が行われる場合、結合条件が存在する場合でも直積結合が選択される場合もある。直接の結合関係にない小さな表同士の直積結合を行い、結合条件のある一方の表と結合するような場合も有り得る

▽特徴

  • 2つの行ソースに対する結合条件がない場合に直積が選択される
  • 結合条件に漏れがないかを確認

▽パフォーマンス

  • 一般的に直積はパフォーマンスが悪いが、スタースキーマ構造となっているDWHシステムでは有効な場合がある

各結合タイプの概要

クロス結合(直積/デカルト積)
  • 2つの表を結合する際に結合条件を明記しない場合に選択される。
  • Oracleは1番目の表の各行と2番目の表の各行を結合する。
  • 直積の行数は1番目の表の行数と2番目の表の行数を掛けた数になる。
内部結合(単純結合)
  • 2つ以上の表を結合し、その結合条件を満たす行のみを返却する。
  • 一般的に結合と言う場合、内部結合を指す。
外部結合
  • 結合される両方の表が結合条件を満たす行も、一方の表には条件を満たす行がない行も全て返却する。
  • 外部結合は内部結合の結果を拡張した位置づけ。
等価結合/非等価結合
  • 等価結合は、結合条件に等価演算子を含む構文のことを言う。
  • 等価結合は、ある特定の列の値が等しい行を結び付ける。
  • 等価演算子以外の演算子で2つの表が結合されている場合は非等価結合。
  • 問合せ文には非等価結合と等価結合も含むことが可能。
自己結合
  • 対象表自身を結合する方法。
  • 自己結合する表はFROM句で2回(あるいはそれ以上)指定され、各表名の後ろには、結合条件やSELECT句の列名を修飾する別名が続く。
アンチジョイン
  • NOT EXISTS句やNOT IN句を用いて記述する。結合条件と一致しない組み合わせを返却する
  • 2つの表をアンチ結合した場合、最初に記述された表に存在し、後に記述された表には存在しない行を返す(右側の副問合せとの結合に失敗した行を戻す)
セミジョイン
  • EXISTS句やIN句を用いて記述する。一致する行が1つ見つかると値を返す。
  • 2つの表を半結合した場合、最初に記述された表に存在する行で、後に記述された表に1行ないしは複数行存在する行を戻す。
  • 半結合と従来の結合との違いは、最初に記述される表の行と一致する行が、後ろに記述される表に複数行存在する場合でも1行しか戻されないという点。
その他
バンド結合(12.2~)
  • 1つのデータセットのキー値が2番目のデータセットの指定された範囲(「バンド」)内になければならない特別なタイプの非等価関数。
  • 同じテーブルは、第1および第2のデータセットの両方として機能することが可能。
  • 12.2以降、データベースはバンド結合をより効率的に評価する。
  • 最適化は、定義されたバンドの外にある行の不必要なスキャンを回避する。
  • オプティマイザはコスト見積もりを使用して、結合方法(ハッシュ/ネストループ/ソートマージ)とパラレルデータ分散方法を選択する。

参考資料

https://docs.oracle.com/cd/E82638_01/TGSQL/toc.htm
Expert Oracle SQL

Expert Oracle SQL: Optimization, Deployment, and Statistics

Expert Oracle SQL: Optimization, Deployment, and Statistics

 

SQL実践入門──高速でわかりやすいクエリの書き方 

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

 

スポンサーリンク