75
<Insert Picture Here> Oracle Direct Seminar 実践!!PL/SQLチューニング 日本オラクル株式会社

Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

<Insert Picture Here>

Oracle Direct Seminar

実践!!PL/SQLチューニング日本オラクル株式会社 

Page 2: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 2

<Insert Picture Here>

アジェンダ

• はじめに• パフォーマンス向上の為のPL/SQLの機能紹介• パフォーマンスを意識したコーディング

※資料中に掲載されている検証内容は、特定の環境に

おける検証結果についての報告であり、すべての環境において同様の動作を保証するものではありませんので予めご了承下さい。

・SQL Serverからの移行アセスメント・MySQLからの移行相談・PostgreSQLからの移行相談・Accessからの移行アセスメント・Application Server 移行相談・Oracle Database バージョンアップ支援・Oracle Developer/2000 Webアップグレード相談・パフォーマンス・クリニック・Oracle Database 構成相談・Oracle Database 高可用性診断・システム連携アセスメント

Oracle Directの無償技術サービス

http://www.oracle.com/lang/jp/direct/services.html

Page 3: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 3

はじめに

• 前提• PL/SQLの基本的な知識がある方を対象としています• 原則として動作確認はOracle Database 11g Enterprise Edition

11.1.0.6にて実施しています※記述がなくても古いバージョンでは使えない可能性があります

• 動作検証環境• マシン:仮想マシン環境• OS: Oracle Enterprise Linux R5 update1 (32bit)• インスタンスはDBCAで全てデフォルトで作成、追加チューニング一切なし

Page 4: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 4

チューニングにかかるコストと利益

アプリケーションの設計から本番稼動までの間のチューニングにかかるコストと利益

コスト

設計 開発 本番

時 間

チューニングにチューニングによって得られる利益よって得られる利益

本日の話

Page 5: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 5

• 最適なコードを書く = 「無駄」を省く

PL/SQLのチューニングとは?

• アプリケーションとしての「無駄」を省く• 言語動作の内部的な動作の「無駄」を省く

•暗黙的に実行される処理を避ける•効率の悪い処理を避ける

•複数の処理を1回の処理で•繰り返し処理を1回の処理で

• 「まとめて」実行する機能を利用する

• SQLも含めて検討する

Page 6: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 6

<Insert Picture Here>

アジェンダ

• はじめに• パフォーマンス向上の為のPL/SQLの機能紹介

• 言語動作の内部的な動作の「無駄」を省く① PL/SQL数値データ型の選択②変数宣言とNOT NULL制約③引数のNOCOPY指定④ PL/SQLファンクション結果キャッシュ⑤ PL/SQLネイティブ・コンパイル

• 「まとめて」実行する機能を利用する• SQLも含めて検討する(SQL新機能紹介)

• パフォーマンスを意識したコーディング

Page 7: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 7

① PL/SQL数値データ型の選択

• 整数を扱う際は、BINARY_INTEGER, PLS_INTEGER, SIMPLE_INTEGERの利用がお勧め• SIMPLE_INTEGERはNULLチェック、オーバーフローチェックが不要な時に利用(チェックのオーバーヘッドが発生しません)

• SIMPLE_INTEGERはネイティブ・コンパイル(後述)時にパフォーマンス向上

整数

-231 ~ 231

×

SIMPLE_INTEGER

浮動小数浮動小数整数整数固定小数浮動小数

数値の種類

倍精度64bit単精度32bit-231 ~ 231-231 ~ 231

1E-130 ~9.99…9E 125、-1E-130 ~

- 9.99…9E 125、0

取り得る値の範囲

○○○○○PL/SQLデータ型

○○××○テーブルデータ型

BINARY_DOUBLE

BINARY_FLOAT

PLS_INTEGER

BINARY_INTEGERNUMBER

11g~

Page 8: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 8

数値データ型によるパフォーマンスの差

CREATE OR REPLACE PROCEDURE num_prefxx ISwk_cnt データ型 := 0;

BEGINFOR cnt IN 0..1000000000 LOOP

wk_cnt := wk_cnt + 1;END LOOP;

END;/

CREATE OR REPLACE PROCEDURE num_prefxx ISwk_cnt データ型 := 0;

BEGINFOR cnt IN 0..1000000000 LOOP

wk_cnt := wk_cnt + 1;END LOOP;

END;/

numberbinary_integerpls_integersimple_integer

のいずれかを指定

※ネイティブ・コンパイラについては後述

0.04

0.12

0.14

0.82

0.34

0.34

0.33

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

simple_integer(NATIVE)

pls_integer(NATIVE)

binary_integer(NATIVE)

number(NATIVE)

simple_integer

pls_integer

binary_integer

number

Page 9: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 9

②変数宣言とNOT NULL制約

• 変数宣言の際にNOT NULL制約をおこなうと、代入の度にNULLチェックがおこなわれるDECLAREvalue1 NUMBER NOT NULL := 0;

BEGINFOR cnt IN 0 .. 1000000000 LOOPvalue1 := 1;END LOOP;

END;/

DECLAREvalue1 NUMBER NOT NULL := 0;

BEGINFOR cnt IN 0 .. 1000000000 LOOPvalue1 := 1;END LOOP;

END;/

代入の度NULLチェックが行われる

0.44

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

NOT NULLなし

NOT NULLあり

DECLAREvalue1 NUMBER := 0;

BEGINFOR cnt IN 0 .. 1000000000 LOOPvalue1 := 1;

END LOOP;END;/

DECLAREvalue1 NUMBER := 0;

BEGINFOR cnt IN 0 .. 1000000000 LOOPvalue1 := 1;

END LOOP;END;/

頻繁に代入される場合、NOT NULL制約をはずす

Page 10: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 10

③引数のNOCOPY指定

• PL/SQLサブプログラムの引数と引数モード

• 引数モード:

• NOCOPYヒントを付けるとOUT、IN OUTでも「参照渡し」が可能

• 「値渡し」は一時変数へのコピーが発生• サイズの大きな変数やデータ構造(レコード等)でメモリー消費や実行速度低下

:値渡し (call by value)IN OUT

: 値渡し (call by value)OUT

: 参照渡し (call by reference )IN

サブプログラム名 (パラメータ名 引数モード(NOCOPY) データ型, …);サブプログラム名 (パラメータ名 引数モード(NOCOPY) データ型, …);

Page 11: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 11

NOCOPY指定によるパフォーマンスの差

DECLARETYPE employees_array_tblIS TABLE OF employees%ROWTYPEINDEX BY pls_integer;employees_array employees_array_tbl;cnt pls_integer := 0;PROCEDURE test(emp_array_out OUT NOCOPY employees_array_tbl)ISBEGINSELECT * BULK COLLECT INTO emp_array_outFROM employees;

END;BEGINtest(employees_array);

END;/

DECLARETYPE employees_array_tblIS TABLE OF employees%ROWTYPEINDEX BY pls_integer;employees_array employees_array_tbl;cnt pls_integer := 0;PROCEDURE test(emp_array_out OUT NOCOPY employees_array_tbl)ISBEGINSELECT * BULK COLLECT INTO emp_array_outFROM employees;

END;BEGINtest(employees_array);

END;/

指定なし・ありで比較

※ employees表:1,000,000件(全件)を  一括で結合配列に

0.73

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

NOCOPYあり

NOCOPYなし

Page 12: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 12

④ PL/SQLファンクションの結果キャッシュ (その①)

• PL/SQLファンクションの結果をSGAにキャッシュし、複数のセッションで利用できるようになりました• PL/SQLファンクションに、結果をキャッシュすることを明記する必要あり• ファンクションおよびパラメータの値を組にして結果をキャッシュ• システムで必要なメモリが足りなくなると古いものから破棄される• ファンクション内で参照している表が変更されるとキャッシュは破棄

• 利用に適したファンクション• ほとんど変更されない情報に依存するもので頻繁に実行されるもの

• マスターテーブルから情報を取得するようなもの• 再帰処理をおこなうもので、何度も同じファンクション+パラメータを利用するもの

• 制限については以下のマニュアルを参考を参照してください• Oracle Database PL/SQL言語リファレンス 11g リリース1(11.1)

11g

EE

Page 13: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 13

PL/SQLファンクションの結果キャッシュ (その②)CREATE OR REPLACE PACKAGE mst IS

FUNCTION get_price(item_id_in IN NUMBER, date_in IN DATE)

RETURN NUMBER RESULT_CACHE;

END mst;

/

CREATE OR REPLACE PACKAGE BODY mst IS

FUNCTION get_price(item_id_in IN NUMBER, date_in IN DATE)

RETURN NUMBER RESULT_CACHE RELIES_ON ( price_list )

IS ret_num NUMBER;

BEGIN

SELECT price INTO ret_num FROM price_list

WHERE item_id = item_id_in

AND from_date <= TRUNC(date_in)

AND to_date > TRUNC(date_in) ;

RETURN ret_num;

END get_price;

END mst;

/

CREATE OR REPLACE PACKAGE mst IS

FUNCTION get_price(item_id_in IN NUMBER, date_in IN DATE)

RETURN NUMBER RESULT_CACHE;

END mst;

/

CREATE OR REPLACE PACKAGE BODY mst IS

FUNCTION get_price(item_id_in IN NUMBER, date_in IN DATE)

RETURN NUMBER RESULT_CACHE RELIES_ON ( price_list )

IS ret_num NUMBER;

BEGIN

SELECT price INTO ret_num FROM price_list

WHERE item_id = item_id_in

AND from_date <= TRUNC(date_in)

AND to_date > TRUNC(date_in) ;

RETURN ret_num;

END get_price;

END mst;

/

キャッシュの有効化

依存する表、Viewの指定

0.00 0.20 0.40 0.60 0.80 1.00 1.20

キャッシュ有り

キャッシュ無し

※ キャッシュ有無で100,000回ループさせた時の差

11g

EE

Page 14: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 14

⑤ PL/SQLのネイティブコンパイル

• PL/SQLのサブプログラムを、プロセッサ固有のネイティブコードにコンパイル、実行することができます。

• PL/SQLサブプログラムを作成する際の、初期化パラメータPLSQL_CODE_TYPE の設定により、ネイティブコンパイルするかどうかが決まる。

- Cコンパイラを利用してコンパイル (要:Cコンパイラ設定)   共有ライブラリの形で利用 (WindowsはDLL、UNIX/Linuxは *.so)- 指定したOS上のディレクトリに共有ライブラリを格納 (要:ディレクトリ指定)

~10gR2

- コンパイラ不要(初期リリースではネイティブコンパイル不可能なプラットフォーム有り)

- SYSTEM表領域上に配置   RAC環境でもバイナリを共有。

11g~

SQL> alter session set plsql_code_type = 'NATIVE';SQL> create or replace procedure …;

Page 15: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 15

ネイティブコンパイルが向くケース

• SQLそのものには効果がありません• SQLでないPL/SQLの演算処理量が多い程効果が高い

• ループ処理や再帰処理などの繰り返しが多い• 文字列演算や数値演算が多い

• 内部でネイティブコンパイルしていないストアド・プログラムを呼び出していると効果は薄い

• 開発環境はデバッグする可能性が高いため、ネイティブコンパイルしない方が良い

Page 16: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 16

ネイティブコンパイルの実行結果

CREATE OR REPLACE PROCEDURE test1 ISTYPE test_tbl_type IS TABLE OF pls_integerINDEX BY pls_integer;

test_tbl test_tbl_type;PROCEDURE test (arg_cnt IN pls_integer,arg_tbl IN OUT NOCOPY test_tbl_type)ISBEGINFOR i IN arg_tbl.FIRST .. arg_tbl.LASTLOOParg_tbl(i) := arg_tbl(i) + i;

END LOOP;END;

-- 隣へ続く

CREATE OR REPLACE PROCEDURE test1 ISTYPE test_tbl_type IS TABLE OF pls_integerINDEX BY pls_integer;

test_tbl test_tbl_type;PROCEDURE test (arg_cnt IN pls_integer,arg_tbl IN OUT NOCOPY test_tbl_type)ISBEGINFOR i IN arg_tbl.FIRST .. arg_tbl.LASTLOOParg_tbl(i) := arg_tbl(i) + i;

END LOOP;END;

-- 隣へ続く

BEGINFOR cnt in 0 .. 10000 LOOPtest_tbl(cnt) := cnt;

END LOOP;FOR cnt in 0 .. 10000 LOOPtest(cnt, test_tbl);

END LOOP;END;/

BEGINFOR cnt in 0 .. 10000 LOOPtest_tbl(cnt) := cnt;

END LOOP;FOR cnt in 0 .. 10000 LOOPtest(cnt, test_tbl);

END LOOP;END;/

exec test1;exec test1;

0.60

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

ネイティブ・コンパイル有

ネイティブ・コンパイル無

Page 17: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 17

<Insert Picture Here>

アジェンダ

• はじめに• パフォーマンス向上の為のPL/SQLの機能紹介

• 言語動作の内部的な動作の「無駄」を省く• 「まとめて」実行する機能を利用する① RETURNING句②バルク処理

• SQLも含めて検討する(SQL新機能紹介)

• パフォーマンスを意識したコーディング

Page 18: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 18

① RETURNING句

• SQLの発行回数を減らすことができる機能• 更新系DML文の操作対象行のうち、指定されたカラムの内容を返す

• 返すデータは複数カラム指定可能

• 返すデータとしてコレクションも指定できる

• 複数件が処理対象になるSQL文でも使える

INSERT INTO … VALUES (…) RETURNING COL1 INTO :COL1;UPDATE … SET … RETURNING COL1 INTO :COL1;DELETE … RETURNING COL1 INTO :COL1;

INSERT INTO … VALUES (…) RETURNING COL1 INTO :COL1;UPDATE … SET … RETURNING COL1 INTO :COL1;DELETE … RETURNING COL1 INTO :COL1;

…… RETURNING COL1, COL2 INTO :COL1, :COL2;…… RETURNING COL1, COL2 INTO :COL1, :COL2;

…… RETURNING COL1 INTO :COL1_ARRAY;…… RETURNING COL1 INTO :COL1_ARRAY;

Page 19: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 19

RETURNING句によるパフォーマンス向上

• 更新系のDML実行と同時に対象行のデータを取得

declareseq number;

begininsert into table1 values(seq1.nextval, 'AAA', 'BBB');select seq1.currval into seq from dual;dbms_output.put_line(seq || 'が採番されました');

end;

declareseq number;

begininsert into table1 values(seq1.nextval, 'AAA', 'BBB');select seq1.currval into seq from dual;dbms_output.put_line(seq || 'が採番されました');

end;

declareseq number;

begininsert into table1 values(seq1.nextval, 'AAA', 'BBB')returning col1 into seq;

dbms_output.put_line(seq || 'が採番されました');

end;

declareseq number;

begininsert into table1 values(seq1.nextval, 'AAA', 'BBB')returning col1 into seq;dbms_output.put_line(seq || 'が採番されました');

end;

上記コードを10万回実行した際のパフォーマンス 0.63

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

RETURNING句使用

RETURNING句不使用

SQLを1回発行SQLを2回発行

Page 20: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 20

②バルク処理 (8i~)

• データ(主にレコード)をまとめて処理する機能• PL/SQLエンジンとSQLエンジンの切り替えを減らすことでパフォーマンスを向上させる• LOOP内でSQLを実行している場合はバルク処理を検討する

PL/SQL エンジン

SQL エンジン

プロシージャ文

エグゼキュータプロシージャPL/SQL

ブロック

SQL文エグゼキュータ

データ

バルク処理なし

PL/SQL エンジン

SQL エンジン

プロシージャ文

エグゼキュータプロシージャPL/SQL

ブロック

SQL文エグゼキュータ

データ

バルク処理あり

SQLSQL

Page 21: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 21

バルク処理(構文)

• FOR ALL (INSERT/UPDATE/DELETE で利用)

• BULK COLLECT(SELECT/FETCH で利用)

FOR i IN depts.FIRST .. depts.LAST LOOPDELETE FROM emp

WHERE dptno = depts(i);END LOOP;

FOR i IN depts.FIRST .. depts.LAST LOOPDELETE FROM emp

WHERE dptno = depts(i);END LOOP;

FORALL i IN depts.FIRST .. depts.LASTDELETE FROM emp

WHERE dptno = depts(i);

FORALL i IN depts.FIRST .. depts.LASTDELETE FROM emp

WHERE dptno = depts(i);

OPEN c1;LOOP

FETCH c1 INTO emp_rec ;EXIT WHEN c1%NOTFOUND;

END LOOP;CLOSE c1;

OPEN c1;LOOP

FETCH c1 INTO emp_rec ;EXIT WHEN c1%NOTFOUND;

END LOOP;CLOSE c1;

OPEN c1;LOOP

FETCH c1 BULK COLLECT INTOemp_rec_tbl LIMIT 200;

EXIT WHEN c1%NOTFOUND;END LOOP;CLOSE c1;

OPEN c1;LOOP

FETCH c1 BULK COLLECT INTOemp_rec_tbl LIMIT 200;

EXIT WHEN c1%NOTFOUND;END LOOP;CLOSE c1;

ループ回数は取得件数と同じ

ループ回数は取得件数の200分の1

バルク処理ありバルク処理なし

バルク処理ありバルク処理なし

Page 22: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 22

FETCH文のバルク処理

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;loopfetch emp_curinto emp_tbl(emp_cur%rowcount);

exit when emp_cur%notfound;end loop;close emp_cur;

end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;loopfetch emp_curinto emp_tbl(emp_cur%rowcount);

exit when emp_cur%notfound;end loop;close emp_cur;

end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;fetch emp_cur bulk collectinto emp_tbl;

close emp_cur;end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;

emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;fetch emp_cur bulk collectinto emp_tbl;

close emp_cur;end;/

10万件で実行した際のパフォーマンス 0.18

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

バルク処理あり

バルク処理なし

Page 23: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 23

SELECT INTO 文のバルク処理

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;loopfetch emp_curinto emp_tbl(emp_cur%rowcount);

exit when emp_cur%notfound;end loop;close emp_cur;

end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;cursor emp_cur is select * from emp;

beginopen emp_cur;loopfetch emp_curinto emp_tbl(emp_cur%rowcount);

exit when emp_cur%notfound;end loop;close emp_cur;

end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;emp_tbl emp_tbl_type;

beginselect * bulk collect into emp_tblfrom emp;

end;/

declaretype emp_tbl_type is table ofemp%rowtype index by pls_integer;

emp_tbl emp_tbl_type;beginselect * bulk collect into emp_tblfrom emp;

end;/

10万件で実行した際のパフォーマンス

0.18

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

バルク処理あり

バルク処理なし

Page 24: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 24

FORALL文によるバルク処理

declaretype emp_tbl_type is table ofemp.empno%type index by pls_integer;emp_tbl emp_tbl_type;

beginselect empno bulk collect into emp_tblfrom emp;for i in emp_tbl.first .. emp_tbl.lastloopupdate emp set sal = sal + 100where empno = emp_tbl(i);

end loop;end;/

declaretype emp_tbl_type is table ofemp.empno%type index by pls_integer;emp_tbl emp_tbl_type;

beginselect empno bulk collect into emp_tblfrom emp;for i in emp_tbl.first .. emp_tbl.lastloopupdate emp set sal = sal + 100where empno = emp_tbl(i);

end loop;end;/

declaretype emp_tbl_type is table ofemp.empno%type index by pls_integer;emp_tbl emp_tbl_type;

beginselect empno bulk collect into emp_tblfrom emp;

forall i in emp_tbl.first.. emp_tbl.lastupdate emp set sal = sal + 100where empno = emp_tbl(i);

end;/

declaretype emp_tbl_type is table ofemp.empno%type index by pls_integer;

emp_tbl emp_tbl_type;beginselect empno bulk collect into emp_tblfrom emp;

forall i in emp_tbl.first.. emp_tbl.lastupdate emp set sal = sal + 100where empno = emp_tbl(i);

end;/

10万件で実行した際のパフォーマンス 0.45

1.00

0.00 0.20 0.40 0.60 0.80 1.00 1.20

バルク処理あり

バルク処理なし

Page 25: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 25

<Insert Picture Here>

アジェンダ

• はじめに• パフォーマンス向上の為のPL/SQLの機能紹介

• 言語動作の内部的な動作の「無駄」を省く• 「まとめて」実行する機能を利用する• SQLも含めて検討する (SQL新機能紹介)① MERGE文② DMLエラー・ロギング

• パフォーマンスを意識したコーディング

Page 26: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 26

① MERGE文(9i R1~)

• MERGE文を使用すると、1つ以上のソースから行を選択し、表またはビューに対して更新および挿入できます

該当レコードがなければ挿入

該当レコードがあれば更新

merge …into

MERGE(UPSERT)

MERGE INTO bonuses D

USING (

SELECT employee_id, salary, department_id

FROM employees

WHERE department_id = 80 ) S

ON (D.employee_id = S.employee_id)

WHEN MATCHED THEN

UPDATE SET D.bonus = D.bonus + S.salary*.01

DELETE WHERE (S.salary > 8000)

WHEN NOT MATCHED THEN

INSERT (D.employee_id, D.bonus)

VALUES (S.employee_id, S.salary*0.1)

WHERE (S.salary <= 8000);

MERGE INTO bonuses D

USING (

SELECT employee_id, salary, department_id

FROM employees

WHERE department_id = 80 ) S

ON (D.employee_id = S.employee_id)

WHEN MATCHED THEN

UPDATE SET D.bonus = D.bonus + S.salary*.01

DELETE WHERE (S.salary > 8000)

WHEN NOT MATCHED THEN

INSERT (D.employee_id, D.bonus)

VALUES (S.employee_id, S.salary*0.1)

WHERE (S.salary <= 8000);

Page 27: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 27

② DMLエラー・ロギング (10g R2~)

• INSERT、UPDATE、MERGE、DELETE文で利用可能• これまでは大量の行を対象とした単一のDMLにエラーが発生すると処理のすべてがロールバックされていました

• 上記DMLに「ERROR LOGS」句をつけることで利用します

• エラー・ロギング表は DBMS_ERRLOG パッケージで作成可能• 実行DMLとエラーロギング表への書き込みトランザクションは分離• DML操作に失敗したデータを記録する為のものであり、すべてのエラーを書き込むものではありません

• 例) ORA-01653(領域不足)、ORA-01555

例) INSERT INTO employees (empno, ename, dptno, sal)( SELECT empno, ename, dptno, sal FROM employees_wk1 )LOG ERRORS INTO ERR$_EMPLOYEES ('WEEKLY_BATCH') REJECT LIMIT 50;

Page 28: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 28

ご参考) エラー・ロギング表の例

INSERT INTO employees (empno, ename, dptno, sal)

( SELECT empno, ename, dptno*1000, sal

FROM employees_old

WHERE empno <= 1)

LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH') REJECT LIMIT 50;

INSERT INTO employees (empno, ename, dptno, sal)

( SELECT empno, ename, dptno*1000, sal

FROM employees_old

WHERE empno <= 1)

LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH') REJECT LIMIT 50;

INSERT でエラー発生 UPDATE でエラー発生対象となるROWID

UPDATE employees

SET dptno = dptno * 1000

WHERE empno = 20

LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH2') REJECT LIMIT 50;

UPDATE employees

SET dptno = dptno * 1000

WHERE empno = 20

LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH2') REJECT LIMIT 50;

故意に桁あふれ

故意に桁あふれ

Page 29: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 29

<Insert Picture Here>

アジェンダ

• はじめに• パフォーマンス向上の為のPL/SQLの機能紹介

• 言語動作の内部的な動作の「無駄」を省く• 「まとめて」実行する機能を利用する• SQLも含めて検討する (SQL新機能紹介)

• MERGE文• DMLエラー・ロギング

• パフォーマンスを意識したコーディング

Page 30: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 30

アプリケーション例での考察 (仕様)

• ワークテーブル(W)の内容をマスターテーブル(M)に反映させる例:• キー項目は同じ• MにWの内容が存在しないデータ(行)はINSERT処理• MにWの内容が存在するデータ(行)はUPDATE処理• エラーが発生した場合に、少なくとも以下の情報を取得

• Oracleのエラー番号、キー項目• エラーが発生しなかったものはすべてMに反映(COMMIT)。大量のエラー(データエラー、システムエラー)が発生した場合、処理を中断(ROLLBACK)

該当レコードがなければ挿入

該当レコードがあれば更新

ワークテーブル(W) マスターテーブル(M)

Page 31: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 31

検証アプリケーションによる比較(前提)

• 検証データ• M(employees)テーブル: 1,000,000件 (平均行長: 26byte)• W(employees_wk1)テーブル: 200,000件 (平均行長: 26byte)

• INSERT対象: 100,000件 (正常系データのみ)• UPDATE対象: 100,000件 (正常系データのみ)

• 比較時の留意事項• M(employees)テーブルはTRUNCATE、INSERTにて測定毎にデータ再作成• M(employees)テーブル再作成後、統計情報取得(dbms_stats.gather_table_stats実施)

• 処理中のREDOログスイッチを避ける為に、事前にログスイッチ• バッファキャッシュにデータ、パッケージがのっていない状態にて実施する為、測定前にDBの再起動を実施

Page 32: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 32

Wの内容をMへ反映(MERGE)処理※ DMLエラー・ロギング機能を利用

ケース5:

1)キー項目の内容がMおよびWに存在するWのデータをそのままMへ反映(UPDATE)処理2)キー項目の内容がMに存在しないWのデータをそのままMへ反映(INSERT)処理※ CURSORを利用しない  DMLエラー・ロギング機能を利用

ケース4:

ケース2のバルク処理※ レコードを使用した挿入・更新機能(Appendix参照)を利用

ケース3:

1)キー項目の内容がMおよびWに存在するWのデータをCURSORにて取得。LOOPにてMへ反映(UPDATE)処理2)キー項目の内容がMに存在しないWのデータをCURSORにて取得

LOOPにてMへ反映(INSERT)処理

ケース2:

Wの内容をCURSORで全件取得。LOOPにてMへの反映処理(INSERTを実施し、キー重複エラーが発生した場合にUPDATE実施)

ケース1:

アプリケーション例での考察 (実装案)

一般的な実装

Page 33: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 33

コーディング時のポイント

• バルク処理(BULK COLLECT INTO..)ではLIMIT指定• 利用する結合配列の要素数を100~200程度にすることでメモリを無駄に使わないようにします

• バルク処理(FORALL)ではSAVE EXCEPTIONS指定• エラーが発生した場合でもバルク処理を完了させ、その後エラー処理をまとめておこなうようにします

• 「DMLエラー・ロギング」の機能を使うことでINSERT、UPDATE、MERGE処理をPL/SQLのバッチ処理に組み込みやすくなりました• これまではDML操作に失敗したデータを明確にする為に、

CURSOR+LOOP処理が必須でした

ケース4

ケース5

ケース3

ケース3

Page 34: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 34

ケース1とケース2の性能比較

• ケース1は例外処理を多発させており非常に効率が悪い

0.0149

1.0000

0.0 0.2 0.4 0.6 0.8 1.0 1.2

ケース2

(キー項目有無)

ケース1

(キー重複エラー)

Page 35: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 35

ケース2とケース3の性能比較

• ケース3はケース2のバルク処理対応• ケース2ではLOOP処理がUPDATEで100,000回、INSERTで

100,000回実行されている• ケース3では一度に200件のバルク処理を実施。LOOP処理が

UPDATEで500回、INSERTで500回に削減している

結合配列要素数: 200

結合配列要素数: 100,000

0.4805

1.0000

0.0 0.2 0.4 0.6 0.8 1.0 1.2

ケース3(バルク処理)

ケース2

Page 36: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 36

ケース3のバルク処理に関する考察

• バルク処理にて結合配列にて利用する要素数を変更し、性能差を比較• ケース3では結合配列で利用する要素数を200にしたものと100,000(全件分)にしたものにて実行

• 実行直後のPGAメモリ量(session pga memory)を比較

34,440,260(byte)結合配列要素数(1,000,000):2,524,228(byte)結合配列要素数( 200):

むやみに結合配列の要素数を増やしても、性能が極端に向上するわけではない

※上記のケースでは、メモリを13倍浪費しているにも関わらず、処理時間はむしろ増加している

1.0488

1.0000

0.0 0.2 0.4 0.6 0.8 1.0 1.2

ケース3 (バルク処理)

ケース3

(バルク処理結合配列要素増加)

Page 37: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 37

ケース3、ケース4、ケース5の性能比較

• こちらのいずれかのケースにてコーディングすることになる• ソースコードが簡潔になるのは、ケース4もしくはケース5• DMLエラー・ロギング機能が動作する際の負荷も存在する

0.2886

0.4233

0.4082

0.6455

0.4805

1.0000

0.0 0.2 0.4 0.6 0.8 1.0 1.2

参考:エラーハンドリング無し

参考:エラーハンドリング無し

ケース2 (CURSOR)

ケース3 (CURSOR + バルク処理)

ケース4

(INSERT,UPDATE + ERROR LOG)

ケース4 (INSERT,UPDATE のみ)

ケース5 (MERGE + ERROR LOG)

ケース5 (MERGEのみ)

Page 38: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 38

レコードを利用した挿入・更新+バルク処理DECLARETYPE tbl_emp_rec IS TABLE OF employees%ROWTYPEINDEX BY PLS_INTEGER;TYPE tbl_empno IS TABLE OF employees.EMPNO%TYPEINDEX BY PLS_INTEGER;emp_rec_array tbl_emp_rec;empno_array tbl_empno;CURSOR emp_rec_upd_cur IS SELECT * FROM employees_wk1;BEGINOPEN emp_rec_upd_cur;LOOPemp_rec_array.DELETE; /* 結合配列の初期化 */empno_array.DELETE;FETCH emp_rec_upd_cur BULK COLLECT INTO emp_rec_array LIMIT 200;IF emp_rec_array.COUNT = 0 THENEXIT;END IF;FOR i IN emp_rec_array.FIRST .. emp_rec_array.LAST LOOPempno_array(i) := emp_rec_array(i).empno;END LOOP;FORALL i IN emp_rec_array.FIRST .. emp_rec_array.LASTUPDATE employeesSET ROW = emp_rec_array(i)WHERE empno = empno_array(i);

EXIT WHEN emp_rec_upd_cur%NOTFOUND;END LOOP;CLOSE emp_rec_upd_cur;END;

一度に200件づつ取得

以下のように書きたいが、FORALL処理中に結合配列の要素を参照できない

FORALL i IN emp_rec_array.FIRST .. emp_rec_array.LASTUPDATE employeesSET ROW = emp_rec_array(i)WHERE empno = emp_rec_array(i).empno;

Page 39: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 39

バルク処理(FORALL)のSAVE EXCEPTIONSDECLARETYPE tbl_exception_index IS TABLE OF VARCHAR2(80)INDEX BY PLS_INTEGER;TYPE tbl_exception_errcode IS TABLE OF PLS_INTEGERINDEX BY PLS_INTEGER;err_index_array tbl_exception_index;err_code_array tbl_exception_errcode;ins_errors PLS_INTEGER := 0;err_count PLS_INTEGER := 0;BEGINOPEN … ;

LOOPFETCH …;BEGINFORALL i IN emp_rec_array.FIRST .. emp_rec_array.LAST SAVE EXCEPTIONSINSERT INTO employees VALUES emp_rec_array(i);

EXCEPTIONWHEN OTHERS THENins_errors := ins_errors + SQL%BULK_EXCEPTIONS.COUNT; -- error件数FOR i IN 1 .. SQL%BULK_EXCEPTIONS.COUNT LOOPerr_count := err_count + 1; -- COUNT UPerr_index_array(err_count) := SUBSTRB(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX,1,80);err_code_array(err_count) := SQL%BULK_EXCEPTIONS(i).ERROR_CODE;END LOOP;

END;EXIT WHEN … %NOTFOUND;END LOOP;CLOSE …;END;

例外が発生しても

まとめて処理

Page 40: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 40

DMLエラー・ロギングの利用 (MERGEの例)DECLARE/* 事前に当該スキーマで実行: execute dbms_errlog.create_error_log('EMPLOYEES'); */ins_errors PLS_INTEGER := 0;upd_errors PLS_INTEGER := 0;BEGINMERGE INTO employees eUSING employees_wk3 wON (e.empno = w.empno)WHEN MATCHED THENUPDATESET e.ename = w.ename,e.dptno = w.dptno,e.sal = w.sal

WHEN NOT MATCHED THENINSERT (e.empno, e.ename, e.dptno, e.sal)VALUES (w.empno, w.ename, w.dptno, w.sal)LOG ERRORS INTO ERR$_EMPLOYEES ('WEEKLY_BATCH') REJECT LIMIT 50;COMMIT;

SELECT count(*) INTO ins_errors FROM err$_employeesWHERE ora_err_tag$ = 'WEEKLY_BATCH' AND ora_err_optyp$ = 'I'; /* INSERT */SELECT count(*) INTO upd_errors FROM err$_employeesWHERE ora_err_tag$ = 'WEEKLY_BATCH' AND ora_err_optyp$ = 'U'; /* UPDATE */

EXCEPTIONWHEN OTHERS THENROLLBACK;

END;/

50件以上エラーがあると全体をROLLBACK。

エラーの情報はERR$_EMPLOYEES表に登録される。

アプリ内部でエラー状況を

把握できる

Page 41: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 41

まとめ

•言語動作の内部的な動作の「無駄」を省く

• 「まとめて」実行する機能を利用する

• (PL/SQLだけではなく)SQLも含めて検討する• ロジックを再検討した方が良い場合もある

Page 42: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 42

【タイトル】年末カレンダー応募【必要情報】1、ご登録の氏名2、ご登録の貴社名、所属部署名3、受講された2009年11月・12月開催のセミナタイトル4、現在ご検討中のシステムについてなど、Oracle Directに相談されたい  ことなどございましたら記載ください。

年末ダイセミ受講感謝キャンペーン

    Oracle Direct Seminarを御愛護頂き、誠にありがとうございます。感謝の気持ちを込めまして、合計100名様にWendy2010年版カレンダーをプレゼントいたします。11月・12月に開催のダイセミを2つ以上受講頂いた方が対象です。是非皆様奮ってご応募下さい!!

応募方法応募方法 [email protected]

必要情報を明記のうえ、メールでご応募ください。当選者の発表は発送をもってかえさせて頂きます。

プレゼントの送付先は、セミナ登録時にご登録されている貴社住所宛てに送付させて頂きます。お客様の登録情報に、a.貴社名、b.部署名、c.役職名、d.住所が正しく登録されていることをご確認ください。a,b,c,dの情報が正しく登録されていない場合はご応募が無効となりますのでご注意下さい。お客様情報の変更はこちらから実施頂けます。

http://www.oracle.com/technology/global/jp/membership/index.html

Page 43: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 43

OTNOTN×ダイセミ でスキルアップ×ダイセミ でスキルアップ!!!!

※OTN掲示版は、基本的にOracleユーザー有志からの回答となるため100%回答があるとは限りません。     ただ、過去の履歴を見ると、質問の大多数に関してなんらかの回答が書き込まれております。

Oracle Technology Network(OTN)を御活用下さい。

・技術的な内容について疑問点を解消したい!・一般的なその解決方法などを知りたい!・セミナ資料など技術コンテンツがほしい!

セミナーに関連する技術的なご質問は、OTN掲示版の「SQLとPL/SQL」へ

http://otn.oracle.co.jp/forum/index.jspa?categoryID=2

過去のセミナ資料、動画コンテンツはOTNの「OTNコンテンツ オン デマンド」へ

http://www.oracle.com/technology/global/jp/ondemand/otn-seminar/index.html

※セミナ事務局にダイセミ資料を請求頂いても、お受けできない可能性がございますので予めご了承ください。  ダイセミ資料はOTNコンテンツ オン デマンドか、セミナ実施時間内にダウンロード頂くようお願い致します。

Page 44: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 44

運用

構築 設計

IT 企画

経営企画

業務改善計画の作成支援• 業務診断サービス• BIアセスメントサービス

システム企画の作成支援•業務診断サービス•BIアセスメントサービス

RFP/提案書の作成支援•BIアセスメントサービス•メインフレーム資産活用相談サービス•仮想化アセスメントサービス•Oracle Database 構成相談サービス•Oracle Database 高可用性クリニック

システム構築時の道案内•Access / SQL Serverからの移行•MySQL / PostgreSQLからの移行•Oracle Database バージョンアップ支援•Oracle Developer Webアップグレード•システム連携アセスメントサービス

システム運用状況の診断•パフォーマンス・クリニック・サービス•システム・セキュリティ診断サービス•データ管理最適化サービス

ITプロジェクト全般に渡る無償支援サービスOracle Direct Conciergeサービスメニュー

Page 45: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 45

http://www.oracle.co.jp/inq_pl/INQUIRY/quest?rid=28

Oracle Direct 検索

あなたにいちばん近いオラクル

Oracle Directまずはお問合せくださいまずはお問合せください

Web問い合わせフォーム フリーダイヤル

専用お問い合わせフォームにてご相談内容を承ります。

※フォームの入力には、Oracle Direct Seminar申込時と同じ  ログインが必要となります。※こちらから詳細確認のお電話を差し上げる場合がありますので、ご登録さ  れている連絡先が最新のものになっているか、ご確認下さい。

0120-155-096 ※月曜~金曜 9:00~12:00、13:00~18:00

  (祝日および年末年始除く)

システムの検討・構築から運用まで、ITプロジェクト全般の相談窓口としてご支援いたします。

システム構成やライセンス/購入方法などお気軽にお問い合わせ下さい。

Page 46: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 46

Appendix

Page 47: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 47

ケース1のソース(主要ロジック部分のみ)①

CREATE OR REPLACE PACKAGE d01

IS

PROCEDURE wrk_to_master;

END d01;

/

show errors

CREATE OR REPLACE PACKAGE BODY d01

IS

emp_rec employees%ROWTYPE;

CURSOR emp_rec_cur IS

SELECT empno,ename,dptno,sal

FROM employees_wk1

ORDER BY empno;

PROCEDURE wrk_to_master

IS

BEGIN

OPEN emp_rec_cur;

LOOP

FETCH emp_rec_cur INTO emp_rec;

EXIT WHEN emp_rec_cur%NOTFOUND;

BEGIN

INSERT INTO employees (

empno,

ename,

dptno,

sal

)VALUES(

emp_rec.empno,

emp_rec.ename,

emp_rec.dptno,

emp_rec.sal

);

EXCEPTION

WHEN DUP_VAL_ON_INDEX THEN

BEGIN

UPDATE employees

SET ename = emp_rec.ename,

dptno = emp_rec.dptno,

sal = emp_rec.sal

WHERE empno = emp_rec.empno;

EXCEPTION

WHEN OTHERS THEN

/* update error */

NULL; /* 本来はエラー処理 */

END;

Page 48: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 48

ケース1のソース(主要ロジック部分のみ)②

WHEN OTHERS THEN

/* insert error */

NULL; /* 本来はエラー処理 */

END;

END LOOP;

CLOSE emp_rec_cur;

COMMIT;

EXCEPTION

WHEN OTHERS THEN

/* error */

IF emp_rec_cur%ISOPEN THEN

CLOSE emp_rec_cur;

END IF;

ROLLBACK;

RAISE;

END wrk_to_master;

END d01;

/

show errors

Page 49: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 49

ケース2のソース(主要ロジック部分のみ)①

CREATE OR REPLACE PACKAGE d02

IS

PROCEDURE wrk_to_master;

END d02;

/

show errors

CREATE OR REPLACE PACKAGE BODY d02

IS

emp_rec employees%ROWTYPE;

CURSOR emp_rec_upd_cur IS

SELECT w.empno, w.ename, w.dptno, w.sal

FROM employees_wk1 w

WHERE EXISTS (

SELECT 'X' FROM employees e

WHERE w.empno = e.empno

)

ORDER BY w.empno;

CURSOR emp_rec_ins_cur IS

SELECT w.empno, w.ename, w.dptno, w.sal

FROM employees_wk1 w

WHERE NOT EXISTS (

SELECT 'X' FROM employees e

WHERE w.empno = e.empno

)

ORDER BY w.empno;

PROCEDURE wrk_to_master

IS

BEGIN

/* まずキー重複しているものをUPDATE */

OPEN emp_rec_upd_cur;

LOOP

FETCH emp_rec_upd_cur INTO emp_rec;

EXIT WHEN emp_rec_upd_cur%NOTFOUND;

BEGIN

UPDATE employees

SET ename = emp_rec.ename,

dptno = emp_rec.dptno,

sal = emp_rec.sal

WHERE empno = emp_rec.empno;

EXCEPTION

WHEN OTHERS THEN

NULL; /* 本来はエラー処理 */

END;

END LOOP;

CLOSE emp_rec_upd_cur;

Page 50: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 50

ケース2のソース(主要ロジック部分のみ)②

/* 次にキー重複していないものをINSERT */

OPEN emp_rec_ins_cur;

LOOP

FETCH emp_rec_ins_cur INTO emp_rec;

EXIT WHEN emp_rec_ins_cur%NOTFOUND;

BEGIN

INSERT INTO employees (

empno,

ename,

dptno,

sal

)VALUES(

emp_rec.empno,

emp_rec.ename,

emp_rec.dptno,

emp_rec.sal

);

EXCEPTION

WHEN OTHERS THEN

NULL; /* 本来はエラー処理 */

END;

END LOOP;

CLOSE emp_rec_ins_cur;

COMMIT;

EXCEPTION

WHEN OTHERS THEN

/* error */

IF emp_rec_upd_cur%ISOPEN THEN

CLOSE emp_rec_upd_cur;

END IF;

IF emp_rec_ins_cur%ISOPEN THEN

CLOSE emp_rec_ins_cur;

END IF;

ROLLBACK;

RAISE;

END wrk_to_master;

END d02;

/

show errors

Page 51: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 51

ケース3のソース(主要ロジック部分のみ)①

CREATE OR REPLACE PACKAGE d03

IS

PROCEDURE wrk_to_master;

END d03;

/

show errors

CREATE OR REPLACE PACKAGE BODY d03

IS

TYPE tbl_emp_rec IS TABLE OF employees%ROWTYPE

INDEX BY PLS_INTEGER;

TYPE tbl_empno IS TABLE OF employees.EMPNO%TYPE

INDEX BY PLS_INTEGER;

emp_rec_array tbl_emp_rec;

empno_array tbl_empno;

CURSOR emp_rec_upd_cur IS

SELECT w.empno, w.ename, w.dptno, w.sal

FROM employees_wk1 w

WHERE EXISTS (

SELECT 'X' FROM employees e

WHERE w.empno = e.empno

)

ORDER BY w.empno;

CURSOR emp_rec_ins_cur IS

SELECT w.empno, w.ename, w.dptno, w.sal

FROM employees_wk1 w

WHERE NOT EXISTS (

SELECT 'X' FROM employees e

WHERE w.empno = e.empno

)

ORDER BY w.empno;

PROCEDURE wrk_to_master

IS

BEGIN

/* まずキー重複しているものをUPDATE */

OPEN emp_rec_upd_cur;

LOOP

emp_rec_array.DELETE; /* 結合配列の初期化 */

empno_array.DELETE;

FETCH emp_rec_upd_cur BULK COLLECT

INTO emp_rec_array LIMIT 200;

IF emp_rec_array.COUNT = 0 THEN

EXIT;

END IF;

FOR i IN emp_rec_array.FIRST ..

emp_rec_array.LAST LOOP

empno_array(i) := emp_rec_array(i).empno;

END LOOP;

Page 52: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 52

ケース3のソース(主要ロジック部分のみ)②

BEGIN

FORALL i IN emp_rec_array.FIRST ..

emp_rec_array.LAST SAVE EXCEPTIONS

UPDATE employees

SET ROW = emp_rec_array(i)

WHERE empno = empno_array(i);

EXCEPTION

WHEN OTHERS THEN

NULL; /* 本来はエラー処理 */

END;

EXIT WHEN emp_rec_upd_cur%NOTFOUND;

END LOOP;

CLOSE emp_rec_upd_cur;

/* 次にキー重複していないものをINSERT */

OPEN emp_rec_ins_cur;

LOOP

emp_rec_array.DELETE; /* 結合配列の初期化 */

FETCH emp_rec_ins_cur BULK COLLECT INTO

emp_rec_array LIMIT 200;

BEGIN

FORALL i IN emp_rec_array.FIRST ..

emp_rec_array.LAST SAVE EXCEPTIONS

INSERT INTO employees

VALUES emp_rec_array(i);

EXCEPTION

WHEN OTHERS THEN

NULL; /* 本来はエラー処理 */

END;

EXIT WHEN emp_rec_ins_cur%NOTFOUND;

END LOOP;

CLOSE emp_rec_ins_cur;

COMMIT;

EXCEPTION

WHEN OTHERS THEN

/* error */

IF emp_rec_upd_cur%ISOPEN THEN

CLOSE emp_rec_upd_cur;

END IF;

IF emp_rec_ins_cur%ISOPEN THEN

CLOSE emp_rec_ins_cur;

END IF;

ROLLBACK;

RAISE;

END wrk_to_master;

END d03;

/

show errors

Page 53: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 53

ケース4のソース(主要ロジック部分のみ)①

CREATE OR REPLACE PACKAGE d04

IS

PROCEDURE wrk_to_master;

END d04;

/

show errors

CREATE OR REPLACE PACKAGE BODY d04

IS

/* 事前に、エラー・ロギング表を作成しておく */

PROCEDURE wrk_to_master

IS

BEGIN

/* まずキー重複しているものをUPDATE */

UPDATE employees e

SET (ename, dptno, sal) = (

SELECT w.ename, w.dptno, w.sal

FROM employees_wk1 w

WHERE w.empno = e.empno

)

WHERE EXISTS (

SELECT 'X' FROM employees_wk1 wk

WHERE e.empno = wk.empno

) LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH') REJECT LIMIT 50;

/* 次にキー重複していないものをINSERT */

INSERT INTO employees (empno,ename,dptno,sal) (

SELECT w.empno, w.ename, w.dptno, w.sal

FROM employees_wk1 w WHERE NOT EXISTS (

SELECT 'X' FROM employees e

WHERE e.empno = w.empno

)

) LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH') REJECT LIMIT 50;

COMMIT;

EXCEPTION

WHEN OTHERS THEN

ROLLBACK;

RAISE;

END wrk_to_master;

END d04;

/

show errors

Page 54: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 54

ケース5のソース(主要ロジック部分のみ)①

CREATE OR REPLACE PACKAGE d05

IS

PROCEDURE wrk_to_master;

END d05;

/

show errors

CREATE OR REPLACE PACKAGE BODY d05

IS

/* 事前に、エラー・ロギング表を作成しておく */

PROCEDURE wrk_to_master

IS

BEGIN

MERGE INTO employees e

USING employees_wk1 w

ON (e.empno = w.empno)

WHEN MATCHED THEN

UPDATE

SET e.ename = w.ename,

e.dptno = w.dptno,

e.sal = w.sal

WHEN NOT MATCHED THEN

INSERT (e.empno, e.ename, e.dptno, e.sal)

VALUES (w.empno, w.ename, w.dptno, w.sal)

LOG ERRORS INTO ERR$_EMPLOYEES

('WEEKLY_BATCH') REJECT LIMIT 50;

COMMIT;

EXCEPTION

WHEN OTHERS THEN

ROLLBACK;

RAISE;

END wrk_to_master;

END d05;

/

show errors

Page 55: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 55

レコードを利用した挿入と更新

• 9iR1以前DECLARE

emp_rec employees%ROWTYPE;

BEGIN

emp_rec.empno := 99;

emp_rec.ename := '従業員名';

emp_rec.dptno := 10;

INSERT INTO employees (empno, ename, dptno)

VALUES (emp_rec.empno,

emp_rec.ename,

emp_rec.dptno);

END;

/

DECLARE

emp_rec employees%ROWTYPE;

BEGIN

emp_rec.empno := 99;

emp_rec.ename := '会社員名';

emp_rec.dptno := 20;

UPDATE employees

SET ename = emp_rec.ename,

dptno = emp_rec.dptno

WHERE empno = emp_rec.empno;

END;

/

INSERT文 UPDATE文

• 9iR2以後INSERT文 UPDATE文DECLARE

emp_rec employees%ROWTYPE;

BEGIN

emp_rec.empno := 99;

emp_rec.ename := '従業員名';

emp_rec.dptno := 10;

INSERT INTO employees VALUES emp_rec;

END;

/

DECLARE

emp_rec employees%ROWTYPE;

BEGIN

emp_rec.empno := 99;

emp_rec.ename := '会社員名';

emp_rec.dptno := 20;

UPDATE employees

SET ROW = emp_rec

WHERE empno = emp_rec.empno;

END;

/

INSERT文 UPDATE文

9iR2

Page 56: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 56

CONTINUE 文

• LOOP制御にCONTINUE文を利用できるようになりました。• CONTINUE文でLOOPの現在処理中の反復を終了し、次のLOOP処理の反復に制御を移します。

• CONTINUE と CONTINUE-WHEN があります。• EXIT(LOOPの終了)と同様、ラベルも使えます。

DECLARE

BEGIN

<<FIRST_LOOP>>

FOR i IN 1 .. 5 LOOP

<<SECOND_LOOP>>

FOR k IN 1 .. 5 LOOP

CASE k

WHEN 2 THEN CONTINUE SECOND_LOOP;

WHEN 4 THEN CONTINUE FIRST_LOOP;

ELSE NULL;

END CASE;

DBMS_OUTPUT.PUT_LINE('i,k: '||TO_CHAR(i)||','||TO_CHAR(k));

END LOOP; /* k */

END LOOP; /* i */

END;

/

DECLARE

BEGIN

<<FIRST_LOOP>>

FOR i IN 1 .. 5 LOOP

<<SECOND_LOOP>>

FOR k IN 1 .. 5 LOOP

CONTINUE SECOND_LOOP WHEN k = 2;

CONTINUE FIRST_LOOP WHEN k = 4;

DBMS_OUTPUT.PUT_LINE('i,k: '||TO_CHAR(i)||','||TO_CHAR(k));

END LOOP; /* k */

END LOOP; /* i */

END;

/

CONTINUE CONTINUE-WHEN

11g

Page 57: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 57

PL/SQL式での sequence の記述

• これまでは SELECT INTO 文にて sequence の値を取得する必要がありましたが、PL/SQL内にて直接値を取得できるようになりました。• 事前に sequenceオブジェクトの定義が必要です。DECLARE

seq_num NUMBER(8);

BEGIN

SELECT tst_seq.nextval INTO seq_num

FROM DUAL;

DBMS_OUTPUT.PUT_LINE('SEQ: '

||TO_CHAR(seq_num));

END;

/

DECLARE

seq_num NUMBER(8);

BEGIN

seq_num := tst_seq.nextval;

DBMS_OUTPUT.PUT_LINE('SEQ: '

||TO_CHAR(seq_num));

END;

/

~ 10gR2 11g ~

11g

Page 58: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 58

PL/SQLサブプログラムの引数の名前表記、混合表記

• デフォルト値を設定しているPL/SQLのファンクションをSQL文中で利用する際に、引数を名前表記、混合表記できるようになりました。• デフォルト値を多く持つファンクションが使いやすくなります。

SELECT compute_bonus(120, 50) FROM dual;

~ 10gR2:位置表記法のみ

SELECT compute_bonus(emp_id => 120, bonus => 50) FROM dual;

名前表記法

SELECT compute_bonus(120, bonus => 50) FROM dual;

混合表記法

11g

Page 59: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 59

複合トリガー

• 複数のタイミングで起動できるDMLトリガーCREATE OR REPLACE TRIGGER compound_triggerFOR UPDATE OF salary ON employeesCOMPOUND TRIGGER-- Declarative part (optional)BEFORE STATEMENT ISBEGINNULL;END BEFORE STATEMENT;

BEFORE EACH ROW ISBEGINNULL;END BEFORE EACH ROW;

AFTER EACH ROW ISBEGINNULL;END AFTER EACH ROW;

AFTER STATEMENT ISBEGINNULL;END AFTER STATEMENT;END compound_trigger;

CREATE OR REPLACE TRIGGER compound_triggerFOR UPDATE OF salary ON employeesCOMPOUND TRIGGER-- Declarative part (optional)BEFORE STATEMENT ISBEGINNULL;END BEFORE STATEMENT;

BEFORE EACH ROW ISBEGINNULL;END BEFORE EACH ROW;

AFTER EACH ROW ISBEGINNULL;END AFTER EACH ROW;

AFTER STATEMENT ISBEGINNULL;END AFTER STATEMENT;END compound_trigger;

•利用が効果的なケース

1. 行単位で処理を行うが、処理そのものはまとめて実施したい

例:ある表への更新情報を別表へ挿入

- AFTER EACH ROW  配列に情報を保持

- AFTER STATEMENT  配列の情報を別表にまとめて挿入

例:ある表のカラムAの平均値を超える更新を許可しない- BEFORE STATEMENT  カラムAの平均値を取得- AFTER EACH ROW  更新値とカラムAの平均値を比較し、  平均値を超えていたらエラー

2. 変更表エラー(ORA-04091 )の回避

11g

Page 60: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 60

<Insert Picture Here>

PL/SQLのデバッグ

Page 61: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 61

PL/SQLのデバッグ方法• DBMS_OUTPUTで値をチェック

• 古いバージョンでも使えるけど原始的• DBMS_DEBUGパッケージ

• PL/SQLアプリケーションの実行をデバッグするためのAPI• ブレークポイントの設定、トレース実行など一通りのデバッグが可能• 使い方が難しい→GUIのPL/SQL開発・デバッグツールを推奨

• GUIのPL/SQL開発・デバッグツール• Oracle JDeveloper• Oracle SQL Developer• Oracle Developer Tools for Visual Studio .NET

Page 62: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 62

<Insert Picture Here>

SQL Developerによるデバッグ

デバッグ対象は、ストアド・プログラムのみ

Page 63: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 63

PL/SQLデバッグ (対象を選択)

ダブルクリック

エディットモードへ

Page 64: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 64

PL/SQLデバッグ(デバッグ用コンパイル)

デバッグ用にコンパイル

行番号表示

右クリックでメニュー表示

Page 65: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 65

PL/SQLデバッグ(ブレイク・ポイントの設定)

左クリックでブレイク・ポイント設定

PL/SQLブロックの折りたたみ可能

Page 66: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 66

PL/SQLデバッグ (開始時点)

デバッグボタンを押すと、デバッグ開始画面

パラメータを設定して「OK」ボタンを押す

Page 67: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 67

デバッグで利用する画面

PL/SQLデバッグ (OKボタン押下直後)

最初のブレイク・ポイントで停止

Page 68: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 68

PL/SQLデバッグ (変数の値の参照・値の変更)

- カウンターで使っている変数 I が3にカウントアップ直後。

-配列はまだ2つしか値がセットされていない。

ステップ毎に実行

Page 69: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 69

<Insert Picture Here>

PL/SQLのプロファイリング

Page 70: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 70

PL/SQLアプリのプロファイリング• プロファイリングとは?

• プログラムの稼動情報を収集し、分析すること• 実行時間• CPU時間• メモリ消費

• パフォーマンス・ボトルネックの調査などに利用• PL/SQLアプリのプロファイリング

• DBMS_PROIFILERパッケージを利用• 各行の実行時間及び実行回数のみ取得可

Oracle8i~

Page 71: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 71

事前準備

1. SYSユーザーで$ORACLE_HOME/rdbms/admin/profload.sqlを実行

- DBMS_PROIFILERパッケージのインストール

2. DBMS_PROIFILERパッケージ実行ユーザーで$ORACLE_HOME/rdbms/admin/proftab.sqlを実行

- DBMS_PROIFILERが使用するテーブルを作成• PLSQL_PROFILER_RUNS

プロファイリングの実行に関する情報を格納

• PLSQL_PROFILER_UNITSプロファイリング対象ユニットに関する情報を格納

• PLSQL_PROFILER_DATAプロファイリングデータを格納

Page 72: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 72

DBMS_PROFILERの使い方1. DBMS_PROFILER.START_PROFILERを実行してプロファイリング開始

- SQL> execute dbms_profiler.start_profiler ('PROFILING SAMPLE1')

2. プロファイリング対象アプリを実行3. DBMS_PROFILER.STOP_PROFILERを実行してプロファイリング終了

- SQL> execute dbms_profiler.stop_profiler

4. プロファイリング情報テーブルを検索- PLSQL_PROFILER_RUNS

- プロファイリング対象アプリの実行ID(RUNID列)を確認- PLSQL_PROFILER_DATA

- プロファイル内容を確認

実行コメントを入れられる

Page 73: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 73

DBMS_PROFILER使用例SQL> execute dbms_profiler.start_profiler ('number_test.' || to_char(sysdate, 'yyyy/mm/dd hh24:mi:ss'))

PL/SQL procedure successfully completed.

SQL> execute number_test

PL/SQL procedure successfully completed.

SQL> execute dbms_profiler.stop_profiler

PL/SQL procedure successfully completed.

SQL> select runid, run_date, run_comment2 from plsql_profiler_runs order by runid;

RUNID RUN_DATE---------- ---------RUN_COMMENT--------------------------------------------------------------------------------

1 20-APR-04number_test.2004/04/20 18:45:56

2 20-APR-04number_test.2004/04/20 18:48:12

プロファイル対象のレコードRUNID=2に注目

プロファイリング開始

プロファイリング対象アプリ実行

プロファイリング終了-- 実行サンプルソースcreate or replace procedure number_test isn number := 1;b binary_integer := 1;p pls_integer := 1;dummy varchar2(20);begindummy := 'start of plsql';for i in 1 .. 100 loopn := n + 1;b := b + 1;p := p + 1;dummy := 'counts for

endloop';end loop;dummy := 'end of plsql';end;

Page 74: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 74

DBMS_PROFILER使用例(続き)SQL> select p.unit_name, p.occured, p.tot_time, p.line# line,2 substr(s.text, 1,75) text3 from4 (select u.unit_name, d.TOTAL_OCCUR occured,5 (d.TOTAL_TIME/1000000000) tot_time, d.line#6 from plsql_profiler_units u, plsql_profiler_data d7 where d.RUNID=u.runid and d.UNIT_NUMBER = u.unit_number8 and d.TOTAL_OCCUR >09 and u.runid = 2) p,10 user_source s11 where p.unit_name = s.name(+) and p.line# = s.line (+)12 order by p.unit_name, p.line#;

UNIT_NAME OCCURED TOT_TIME LINE TEXT--------------- ------- ----------- ---------- -----------------------------------NUMBER_TEST 1 .002074 2 n number := 1;NUMBER_TEST 1 .000388 3 b binary_integer := 1;NUMBER_TEST 1 .000068 4 p pls_integer := 1;NUMBER_TEST 1 .001185 7 dummy := 'start of plsql';NUMBER_TEST 101 .030679 8 for i in 1 .. 100 loopNUMBER_TEST 100 .027835 9 n := n + 1;NUMBER_TEST 100 .046406 10 b := b + 1;NUMBER_TEST 100 .009543 11 p := p + 1;NUMBER_TEST 100 .014314 12 dummy := 'counts for endloop';NUMBER_TEST 1 .001272 14 dummy := 'end of plsql';

9行目:RUNIDを入力(例だと2)

単位:ナノ秒

Page 75: Oracle Direct Seminar...2009/12/17  · ・PostgreSQLからの移行相談 ・Accessからの移行アセスメント ・Application Server 移行相談 ・Oracle Database バージョンアップ支援

Copyright© 2009, Oracle. All rights reserved. 75

以上の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することをコミットメント(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さい。オラクル製品に関して記載されている機能の開発、リリースおよび時期については、弊社の裁量により決定されます。

Oracle、PeopleSoft、JD Edwards、及びSiebelは、米国オラクル・コーポレーション及びその子会社、関連会社の登録商標です。その他の名称はそれぞれの会社の商標の可能性があります。