JPOUG in 15 minutes #8
三原 健一
自己紹介
• フリーランス
• 現在:大手SIerの性能問題解決チームに従事
• 過去1年数ヶ月は主にSQLチューニングの日々
• ブログ:「サイクル&オラクル」
http://onefact.jp/wp/
• DB Online記事執筆:「Oracle技術者から見た、SAP HANA」
https://enterprisezine.jp/article/corner/440
アジェンダ
• 実行計画ツリーとその見方
• 実行計画を見やすくするTips
• チューニングの実際
SELECT /*+ ONLINE_SQL04S
INDEX(T004 I_TABLE004_8) INDEX(T001 I_TABLE001_2)
USE_NL(T002)
LEADING(T001 T004 T002) */
COUNT(*) AS COUNTNUM
FROM
TABLE_004 T004
INNER JOIN
TABLE_001 T001
ON (T004.COL3091 = T001.COL3091
AND T004.COLA269 = T001.COLA269)
LEFT OUTER JOIN
TABLE_002 T002
ON (T002.COLA215 = T001.COLA215
AND T002.COL3091 = T004.COL3091)
WHERE
..... 以下省略 ..........
COUNTNUM
----------
1
経過: 00:03:27.35
チューニング前SQLと実行結果
← オンラインSQLなので目標レスポンス時間は3秒以内
Plan hash value: 239732999
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts || A-Rows | A-Time ||
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 || 1 |00:03:27.34 ||
| 1 | SORT AGGREGATE | | 1 || 1 |00:03:27.34 ||
|* 2 | COUNT STOPKEY | | 1 || 1 |00:03:27.34 ||
|* 3 | FILTER | | 1 || 1 |00:03:27.34 ||
|* 4 | FILTER | | 1 || 1 |00:03:27.34 ||
| 5 | NESTED LOOPS OUTER | | 1 || 1 |00:03:27.34 ||
| 6 | NESTED LOOPS | | 1 || 1 |00:03:27.33 ||
|* 7 | TABLE ACCESS BY INDEX ROWID BATCHED | TABLE_001 | 1 || 3060 |00:00:03.12 ||
|* 8 | INDEX SKIP SCAN | I_TABLE001_2 | 1 || 3060 |00:00:02.96 ||
| 9 | PARTITION RANGE ITERATOR | | 3060 || 1 |00:03:24.20 ||
|* 10 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| TABLE_004 | 3060 || 1 |00:03:24.19 ||
|* 11 | INDEX RANGE SCAN | I_TABLE004_8 | 3060 || 1 |00:03:24.17 ||
|* 12 | INDEX RANGE SCAN | I_TABLE002PK | 1 || 0 |00:00:00.01 ||
----------------------------------------------------------------------------------------------------------
参考:「SQLチューニングに必要な考え方と最新テクニック」by 日本オラクル 柴田 歩氏
https://www.oracle.com/webfolder/technetwork/jp/ondemand/ddd2013/A-1.pdf
実行統計を併記した実行計画の表示方法と読み方のおさらい
Starts: 当該ステップの実行回数 A-Rows: 処理行数 A-Time: 実行時間
実行順:11 -> 10 -> 9 -> 8 -> 7 -> 6 -> 12 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0
⑥ NESTED LOOPS
Rows=1 Time=204.20s
TABLE_001
駆動表(外部表)
TABLE_004
内部表
Starts=1
続く
⑧ INDEX SKIP SCAN
A-Rows=3,060 Time=2.96s
⑦ TABLE ACCESS BY INDEX ROWID BATCHED
A-Rows=3,060 Time=3.12s
+0.16s
⑪ INDEX RANGE SCAN
Rows=1 Time=204.17s
+0.02s
⑩ TABLE ACCESS BY INDEX ROWID BATCHED
Rows=1 Time=204.19s
⑨ PARTITION RANGE ITERATOR
Rows=1 Time=204.20s
+0.01s
Starts=3,060
Nested Loops Joinの動作
ID Operation Name Starts A-Rows A-Time
-- ------------------------------------------------- -------------- ------ ------ ------
8 INDEX SKIP SCAN I_TABLE001_2 1 3,060 2.96
7 TABLE ACCESS BY INDEX ROWID BATCHED TABLE_001 1 3,060 3.12
11 INDEX RANGE SCAN I_TABLE004_8 3,060 1 204.17
10 TABLE ACCESS BY LOCAL INDEX ROWID BATCHED TABLE_004 3,060 1 204.19
9 PARTITION RANGE ITERATOR 3,060 1 204.20
6 NESTED LOOPS 1 1 207.33
12 INDEX RANGE SCAN I_TABLE002PK 1 0 0.00
5 NESTED LOOPS OUTER 1 1 207.34
4 FILTER 1 1 207.34
3 FILTER 1 1 207.34
2 COUNT STOPKEY 1 1 207.34
1 SORT AGGREGATE 1 1 207.34
0 SELECT STATEMENT 1 1 207.34
13行が選択されました。
実行順実行計画の表示
• 上から下に向かって単純にたどっていく
• ID=0のA-Timeが全体の実行時間(< 経過時間)
• A-Timeが最も急激に増加しているステップがボトルネック(ID=11)
• ボトルネックの手前にも問題点がないか確認(ID=8)
⇨ チューニング・ポイント:2つのインデックスを見直す
01 select
02 ID,"Operation","Name","Starts","E-Rows","A-Rows","A-Time","Buffers","Reads","Writes","Srch Cols","Pstart","Pstop","PartID"
03 from
04 (select
05 rownum NO
06 ,ID
07 ,lpad(' ',DEPTH) || OPERATION ||' '|| OPTIONS "Operation"
08 ,OBJECT_NAME "Name" ,LAST_STARTS "Starts"
09 ,nvl(CARDINALITY,1) * LAST_STARTS "E-Rows" -- 1回の操作で処理される見積行数 * 見積処理回数 = 見積処理行数
10 ,LAST_OUTPUT_ROWS "A-Rows" -- 実際の処理行数
11 ,LAST_ELAPSED_TIME/1000000 "A-Time"
12 ,LAST_CR_BUFFER_GETS "Buffers",LAST_DISK_READS "Reads",LAST_DISK_WRITES "Writes"
13 ,SEARCH_COLUMNS "Srch Cols"
14 --,COST
15 ,PARTITION_START "Pstart",PARTITION_STOP "Pstop",PARTITION_ID "PartID"
16 from
17 (select a.* from
18 V$SQL_PLAN_STATISTICS_ALL a
19 where a.SQL_ID = '&1'
20 and a.TIMESTAMP = (select max(b.TIMESTAMP) from V$SQL_PLAN_STATISTICS_ALL b where b.SQL_ID = a.SQL_ID)
21 )
22 start with PARENT_ID is null
23 connect by prior ID = PARENT_ID
24 order siblings by ID desc
25 )
26 order by NO desc
27 ;
「実行順実行計画」表示スクリプト(全体)
15 ,PARTITION_START "Pstart",PARTITION_STOP "Pstop",PARTITION_ID "PartID"
16 from
17 (select a.* from
18 V$SQL_PLAN_STATISTICS_ALL a
19 where a.SQL_ID = '&1'
20 and a.TIMESTAMP = (select max(b.TIMESTAMP) from
V$SQL_PLAN_STATISTICS_ALL b where b.SQL_ID = a.SQL_ID)
21 )
22 start with PARENT_ID is null
23 connect by prior ID = PARENT_ID
24 order siblings by ID desc
25 )
「実行順実行計画」表示スクリプト(詳細1)
• 18行目:DBMS_XPLAN.DISPLAY_CURSORの参照元
• 22〜23行目:階層問い合わせで親IDから順にたどる
• 24行目:SIBLINGS(きょうだい) f.e. sibling node きょうだいノード
• 20行目:(念のため)直近の実行計画に絞る
01 select
02 ID,"Operation","Name","Starts","E-Rows","A-Rows","A-Time","Buffers","Reads","Writes","Srch
Cols","Pstart","Pstop","PartID"
03 from
04 (select
05 rownum NO
06 ,ID
07 ,lpad(' ',DEPTH) || OPERATION ||' '|| OPTIONS "Operation"
08 ,OBJECT_NAME "Name" ,LAST_STARTS "Starts"
09 ,nvl(CARDINALITY,1) * LAST_STARTS "E-Rows" -- 1回の操作で処理される見積行数 * 見積処理回
数 = 見積処理行数
10 ,LAST_OUTPUT_ROWS "A-Rows" -- 実際の処理行数
11 ,LAST_ELAPSED_TIME/1000000 "A-Time"
.............................................................................
25 )
26 order by NO desc
27 ;
「実行順実行計画」表示スクリプト(詳細2)
• 05および26行目:実行順を上から順に表示させるため
• 09行目:(念のため)E-Rowsを使いやすい値に加工する
SELECT /*+ ONLINE_SQL04S
INDEX(T004 I_TABLE004_TEST2) INDEX(T001 I_TABLE001_TEST1)
USE_NL(T002) LEADING(T001 T004 T002) */
COUNT(*) AS COUNTNUM
FROM
TABLE_004 T004
INNER JOIN
TABLE_001 T001
ON (T004.COL3091 = T001.COL3091
AND T004.COLA269 = T001.COLA269)
LEFT OUTER JOIN
TABLE_002 T002
ON (T002.COLA215 = T001.COLA215
AND T002.COL3091 = T004.COL3091)
WHERE
..... 以下省略 ..........
COUNTNUM
----------
1
経過: 00:00:01.04
チューニング後SQLと実行結果
2つの複合インデックスのカラム順を見直し
3:27.35 ⇨ 1.04 に改善
Plan hash value: 1704335308
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts || A-Rows | A-Time ||
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 || 1 |00:00:00.09 ||
| 1 | SORT AGGREGATE | | 1 || 1 |00:00:00.09 ||
|* 2 | COUNT STOPKEY | | 1 || 1 |00:00:00.09 ||
|* 3 | FILTER | | 1 || 1 |00:00:00.09 ||
|* 4 | FILTER | | 1 || 1 |00:00:00.09 ||
| 5 | NESTED LOOPS OUTER | | 1 || 1 |00:00:00.09 ||
| 6 | MERGE JOIN | | 1 || 1 |00:00:00.09 ||
|* 7 | TABLE ACCESS BY INDEX ROWID | TABLE_001 | 1 || 3060 |00:00:00.09 ||
|* 8 | INDEX RANGE SCAN | I_TABLE001_TEST1 | 1 || 3060 |00:00:00.01 ||
|* 9 | FILTER | | 3060 || 1 |00:00:00.01 ||
|* 10 | SORT JOIN | | 3060 || 1 |00:00:00.01 ||
| 11 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| TABLE_004 | 1 || 1 |00:00:00.01 ||
|* 12 | INDEX RANGE SCAN | I_TABLE004_TEST2 | 1 || 1 |00:00:00.01 ||
|* 13 | INDEX RANGE SCAN | I_TABLE002PK | 1 || 0 |00:00:00.01 ||
----------------------------------------------------------------------------------------------------------------
ID Operation Name Starts E-Rows A-Rows A-Time
-- --------------------------------------------------- ---------------- ------ ------ ------ ------
8 INDEX RANGE SCAN I_TABLE001_TEST1 1 38,050 3,060 0.01
7 TABLE ACCESS BY INDEX ROWID TABLE_001 1 38,046 3,060 0.09
12 INDEX RANGE SCAN I_TABLE004_TEST2 1 1 1 0.00
11 TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED TABLE_004 1 1 1 0.00
10 SORT JOIN 3,060 3,060 1 0.00
9 FILTER 3,060 3,060 1 0.01
6 MERGE JOIN 1 1 1 0.09
13 INDEX RANGE SCAN I_TABLE002PK 1 1 0 0.00
5 NESTED LOOPS OUTER 1 1 1 0.09
4 FILTER 1 1 1 0.09
3 FILTER 1 1 1 0.09
2 COUNT STOPKEY 1 1 1 0.09
1 SORT AGGREGATE 1 1 1 0.09
0 SELECT STATEMENT 1 1 1 0.09
チューニング後実行計画
まとめ
• 実行統計(10gR2〜)はOracle技術者にとっての大きな飛躍
• 実行順表示でボトルネックはさらにわかりやすく
• ボトルネック解消策
• SCAN / ACCESS : インデックス等I/O負荷削減検討
• JOIN : 結合方式検討(USE_HASHヒント等)、結合順序検
討(LEADINGヒント等)
• 詳しくはブログで。。。

実行統計による実践的SQLチューニング

  • 1.
    JPOUG in 15minutes #8 三原 健一
  • 2.
    自己紹介 • フリーランス • 現在:大手SIerの性能問題解決チームに従事 •過去1年数ヶ月は主にSQLチューニングの日々 • ブログ:「サイクル&オラクル」 http://onefact.jp/wp/ • DB Online記事執筆:「Oracle技術者から見た、SAP HANA」 https://enterprisezine.jp/article/corner/440
  • 3.
  • 4.
    SELECT /*+ ONLINE_SQL04S INDEX(T004I_TABLE004_8) INDEX(T001 I_TABLE001_2) USE_NL(T002) LEADING(T001 T004 T002) */ COUNT(*) AS COUNTNUM FROM TABLE_004 T004 INNER JOIN TABLE_001 T001 ON (T004.COL3091 = T001.COL3091 AND T004.COLA269 = T001.COLA269) LEFT OUTER JOIN TABLE_002 T002 ON (T002.COLA215 = T001.COLA215 AND T002.COL3091 = T004.COL3091) WHERE ..... 以下省略 .......... COUNTNUM ---------- 1 経過: 00:03:27.35 チューニング前SQLと実行結果 ← オンラインSQLなので目標レスポンス時間は3秒以内
  • 5.
    Plan hash value:239732999 ---------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts || A-Rows | A-Time || ---------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 || 1 |00:03:27.34 || | 1 | SORT AGGREGATE | | 1 || 1 |00:03:27.34 || |* 2 | COUNT STOPKEY | | 1 || 1 |00:03:27.34 || |* 3 | FILTER | | 1 || 1 |00:03:27.34 || |* 4 | FILTER | | 1 || 1 |00:03:27.34 || | 5 | NESTED LOOPS OUTER | | 1 || 1 |00:03:27.34 || | 6 | NESTED LOOPS | | 1 || 1 |00:03:27.33 || |* 7 | TABLE ACCESS BY INDEX ROWID BATCHED | TABLE_001 | 1 || 3060 |00:00:03.12 || |* 8 | INDEX SKIP SCAN | I_TABLE001_2 | 1 || 3060 |00:00:02.96 || | 9 | PARTITION RANGE ITERATOR | | 3060 || 1 |00:03:24.20 || |* 10 | TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| TABLE_004 | 3060 || 1 |00:03:24.19 || |* 11 | INDEX RANGE SCAN | I_TABLE004_8 | 3060 || 1 |00:03:24.17 || |* 12 | INDEX RANGE SCAN | I_TABLE002PK | 1 || 0 |00:00:00.01 || ---------------------------------------------------------------------------------------------------------- 参考:「SQLチューニングに必要な考え方と最新テクニック」by 日本オラクル 柴田 歩氏 https://www.oracle.com/webfolder/technetwork/jp/ondemand/ddd2013/A-1.pdf 実行統計を併記した実行計画の表示方法と読み方のおさらい Starts: 当該ステップの実行回数 A-Rows: 処理行数 A-Time: 実行時間 実行順:11 -> 10 -> 9 -> 8 -> 7 -> 6 -> 12 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0
  • 6.
    ⑥ NESTED LOOPS Rows=1Time=204.20s TABLE_001 駆動表(外部表) TABLE_004 内部表 Starts=1 続く ⑧ INDEX SKIP SCAN A-Rows=3,060 Time=2.96s ⑦ TABLE ACCESS BY INDEX ROWID BATCHED A-Rows=3,060 Time=3.12s +0.16s ⑪ INDEX RANGE SCAN Rows=1 Time=204.17s +0.02s ⑩ TABLE ACCESS BY INDEX ROWID BATCHED Rows=1 Time=204.19s ⑨ PARTITION RANGE ITERATOR Rows=1 Time=204.20s +0.01s Starts=3,060 Nested Loops Joinの動作
  • 7.
    ID Operation NameStarts A-Rows A-Time -- ------------------------------------------------- -------------- ------ ------ ------ 8 INDEX SKIP SCAN I_TABLE001_2 1 3,060 2.96 7 TABLE ACCESS BY INDEX ROWID BATCHED TABLE_001 1 3,060 3.12 11 INDEX RANGE SCAN I_TABLE004_8 3,060 1 204.17 10 TABLE ACCESS BY LOCAL INDEX ROWID BATCHED TABLE_004 3,060 1 204.19 9 PARTITION RANGE ITERATOR 3,060 1 204.20 6 NESTED LOOPS 1 1 207.33 12 INDEX RANGE SCAN I_TABLE002PK 1 0 0.00 5 NESTED LOOPS OUTER 1 1 207.34 4 FILTER 1 1 207.34 3 FILTER 1 1 207.34 2 COUNT STOPKEY 1 1 207.34 1 SORT AGGREGATE 1 1 207.34 0 SELECT STATEMENT 1 1 207.34 13行が選択されました。 実行順実行計画の表示 • 上から下に向かって単純にたどっていく • ID=0のA-Timeが全体の実行時間(< 経過時間) • A-Timeが最も急激に増加しているステップがボトルネック(ID=11) • ボトルネックの手前にも問題点がないか確認(ID=8) ⇨ チューニング・ポイント:2つのインデックスを見直す
  • 8.
    01 select 02 ID,"Operation","Name","Starts","E-Rows","A-Rows","A-Time","Buffers","Reads","Writes","SrchCols","Pstart","Pstop","PartID" 03 from 04 (select 05 rownum NO 06 ,ID 07 ,lpad(' ',DEPTH) || OPERATION ||' '|| OPTIONS "Operation" 08 ,OBJECT_NAME "Name" ,LAST_STARTS "Starts" 09 ,nvl(CARDINALITY,1) * LAST_STARTS "E-Rows" -- 1回の操作で処理される見積行数 * 見積処理回数 = 見積処理行数 10 ,LAST_OUTPUT_ROWS "A-Rows" -- 実際の処理行数 11 ,LAST_ELAPSED_TIME/1000000 "A-Time" 12 ,LAST_CR_BUFFER_GETS "Buffers",LAST_DISK_READS "Reads",LAST_DISK_WRITES "Writes" 13 ,SEARCH_COLUMNS "Srch Cols" 14 --,COST 15 ,PARTITION_START "Pstart",PARTITION_STOP "Pstop",PARTITION_ID "PartID" 16 from 17 (select a.* from 18 V$SQL_PLAN_STATISTICS_ALL a 19 where a.SQL_ID = '&1' 20 and a.TIMESTAMP = (select max(b.TIMESTAMP) from V$SQL_PLAN_STATISTICS_ALL b where b.SQL_ID = a.SQL_ID) 21 ) 22 start with PARENT_ID is null 23 connect by prior ID = PARENT_ID 24 order siblings by ID desc 25 ) 26 order by NO desc 27 ; 「実行順実行計画」表示スクリプト(全体)
  • 9.
    15 ,PARTITION_START "Pstart",PARTITION_STOP"Pstop",PARTITION_ID "PartID" 16 from 17 (select a.* from 18 V$SQL_PLAN_STATISTICS_ALL a 19 where a.SQL_ID = '&1' 20 and a.TIMESTAMP = (select max(b.TIMESTAMP) from V$SQL_PLAN_STATISTICS_ALL b where b.SQL_ID = a.SQL_ID) 21 ) 22 start with PARENT_ID is null 23 connect by prior ID = PARENT_ID 24 order siblings by ID desc 25 ) 「実行順実行計画」表示スクリプト(詳細1) • 18行目:DBMS_XPLAN.DISPLAY_CURSORの参照元 • 22〜23行目:階層問い合わせで親IDから順にたどる • 24行目:SIBLINGS(きょうだい) f.e. sibling node きょうだいノード • 20行目:(念のため)直近の実行計画に絞る
  • 10.
    01 select 02 ID,"Operation","Name","Starts","E-Rows","A-Rows","A-Time","Buffers","Reads","Writes","Srch Cols","Pstart","Pstop","PartID" 03from 04 (select 05 rownum NO 06 ,ID 07 ,lpad(' ',DEPTH) || OPERATION ||' '|| OPTIONS "Operation" 08 ,OBJECT_NAME "Name" ,LAST_STARTS "Starts" 09 ,nvl(CARDINALITY,1) * LAST_STARTS "E-Rows" -- 1回の操作で処理される見積行数 * 見積処理回 数 = 見積処理行数 10 ,LAST_OUTPUT_ROWS "A-Rows" -- 実際の処理行数 11 ,LAST_ELAPSED_TIME/1000000 "A-Time" ............................................................................. 25 ) 26 order by NO desc 27 ; 「実行順実行計画」表示スクリプト(詳細2) • 05および26行目:実行順を上から順に表示させるため • 09行目:(念のため)E-Rowsを使いやすい値に加工する
  • 11.
    SELECT /*+ ONLINE_SQL04S INDEX(T004I_TABLE004_TEST2) INDEX(T001 I_TABLE001_TEST1) USE_NL(T002) LEADING(T001 T004 T002) */ COUNT(*) AS COUNTNUM FROM TABLE_004 T004 INNER JOIN TABLE_001 T001 ON (T004.COL3091 = T001.COL3091 AND T004.COLA269 = T001.COLA269) LEFT OUTER JOIN TABLE_002 T002 ON (T002.COLA215 = T001.COLA215 AND T002.COL3091 = T004.COL3091) WHERE ..... 以下省略 .......... COUNTNUM ---------- 1 経過: 00:00:01.04 チューニング後SQLと実行結果 2つの複合インデックスのカラム順を見直し 3:27.35 ⇨ 1.04 に改善
  • 12.
    Plan hash value:1704335308 ---------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts || A-Rows | A-Time || ---------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 || 1 |00:00:00.09 || | 1 | SORT AGGREGATE | | 1 || 1 |00:00:00.09 || |* 2 | COUNT STOPKEY | | 1 || 1 |00:00:00.09 || |* 3 | FILTER | | 1 || 1 |00:00:00.09 || |* 4 | FILTER | | 1 || 1 |00:00:00.09 || | 5 | NESTED LOOPS OUTER | | 1 || 1 |00:00:00.09 || | 6 | MERGE JOIN | | 1 || 1 |00:00:00.09 || |* 7 | TABLE ACCESS BY INDEX ROWID | TABLE_001 | 1 || 3060 |00:00:00.09 || |* 8 | INDEX RANGE SCAN | I_TABLE001_TEST1 | 1 || 3060 |00:00:00.01 || |* 9 | FILTER | | 3060 || 1 |00:00:00.01 || |* 10 | SORT JOIN | | 3060 || 1 |00:00:00.01 || | 11 | TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED| TABLE_004 | 1 || 1 |00:00:00.01 || |* 12 | INDEX RANGE SCAN | I_TABLE004_TEST2 | 1 || 1 |00:00:00.01 || |* 13 | INDEX RANGE SCAN | I_TABLE002PK | 1 || 0 |00:00:00.01 || ---------------------------------------------------------------------------------------------------------------- ID Operation Name Starts E-Rows A-Rows A-Time -- --------------------------------------------------- ---------------- ------ ------ ------ ------ 8 INDEX RANGE SCAN I_TABLE001_TEST1 1 38,050 3,060 0.01 7 TABLE ACCESS BY INDEX ROWID TABLE_001 1 38,046 3,060 0.09 12 INDEX RANGE SCAN I_TABLE004_TEST2 1 1 1 0.00 11 TABLE ACCESS BY GLOBAL INDEX ROWID BATCHED TABLE_004 1 1 1 0.00 10 SORT JOIN 3,060 3,060 1 0.00 9 FILTER 3,060 3,060 1 0.01 6 MERGE JOIN 1 1 1 0.09 13 INDEX RANGE SCAN I_TABLE002PK 1 1 0 0.00 5 NESTED LOOPS OUTER 1 1 1 0.09 4 FILTER 1 1 1 0.09 3 FILTER 1 1 1 0.09 2 COUNT STOPKEY 1 1 1 0.09 1 SORT AGGREGATE 1 1 1 0.09 0 SELECT STATEMENT 1 1 1 0.09 チューニング後実行計画
  • 13.
    まとめ • 実行統計(10gR2〜)はOracle技術者にとっての大きな飛躍 • 実行順表示でボトルネックはさらにわかりやすく •ボトルネック解消策 • SCAN / ACCESS : インデックス等I/O負荷削減検討 • JOIN : 結合方式検討(USE_HASHヒント等)、結合順序検 討(LEADINGヒント等) • 詳しくはブログで。。。