IT Soldier Sakuri !!

Oracle使い。いつのまにかIT戦士になってしまったさくりの可哀想な奮闘記。

Oracle活用 どっちのSQLにしようか迷ったら実行計画を使ってみる!

明日から8連休の夏休みに突入ぅぅううううう!
気分が開放的になっとります!
夏休みに向けて髪も綺麗に染めて参りましたぁっ!!
ひゃっほーーーう!



Oracle活用 重複排除はGROUP BYではなくてDISTINCTを使うべし!で書いていた
実行計画について調べたのでφ(゚-゚=)メモニャン

簡単にいうと…
実行計画とはSQLを実行したときにどんな順番でSQLが処理されていくのかを解説してくれる機能。

どっちのSQLの方がパフォーマンスいいんだろう?
ってときに実行すれば、こっちの方が効率よくテーブルにアクセスしてるじゃん!
ってことがわかる。

実行計画を出す方法①

EXPLAIN PLAN FOR [解析したいSQL]
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());

実際にやってみると…

22:46:38 SQL> explain plan for select * from employees where department_id = '110';

解析されました。

22:46:49 SQL> select plan_table_output from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------
Plan hash value: 2056577954

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |     2 |   138 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |     2 |   138 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |     2 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

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

   2 - access("DEPARTMENT_ID"=110)

14行が選択されました。

22:46:59 SQL>

ええええ!?
「解析されました」ってそれだけ?結果は?結果はもらえないの?
とちょっとびっくりした。
しかも、いちいち実行計画のテーブルにアクセスして結果を見ないといけないのが面倒かも。

と、思ったら、こんな方法があった!
というかこっちの方が一般的みたい。

実行計画を出す方法②

SET AUTOTRACE ON EXPLAIN
[解析&実行したいSQL]
SET AUTOTRACE OFF

SETを打っておけばそれ以降のSQLは実行結果と共に、実行計画も表示される。
最後にまたSETでOFFにしておけばいいみたい。

22:46:59 SQL> SET AUTOTRACE ON EXPLAIN
22:57:08 SQL> select * from employees where department_id = '100';

EMPLOYEE_ID FIRST_NAME                               LAST_NAME
----------- ---------------------------------------- ----------------------------------------------
        108 Nancy                                    Greenberg
        109 Daniel                                   Faviet
        110 John                                     Chen
        111 Ismael                                   Sciarra
        112 Jose Manuel                              Urman
        113 Luis                                     Popp

6行が選択されました。


実行計画
----------------------------------------------------------
Plan hash value: 2056577954

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |     6 |   414 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |     6 |   414 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_DEPARTMENT_IX |     6 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

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

   2 - access("DEPARTMENT_ID"=100)

22:57:26 SQL> SET AUTOTRACE OFF
22:58:43 SQL>

これなら実行結果も実行計画もいっぺんに出てくるので、楽チン!!

ちょっと単純なSQL過ぎるけど、意味はこんな感じ。

Id 実行順序
Operation 実行内容
Name アクセスしたTableやIndexの名前
Rows 行数
Byte アクセスされるバイト数(目安)
Cost(%CPU) 操作コストの見積もり
Time かかった時間

なので、Operationを見てどんな順番にどんな処理がされているのかを確認して、
Costでどのくらいの処理力が必要なのかを見るって感じかな。

もうちょっと複雑なSQLを実行して、処理を追ってみようかな。