Tips1. Oracleのパフォーマンス問題~存在チェックが遅い~
存在チェックにCOUNTを使わない!
もう、世の中的にはPL/SQLも古い言語に含まれると思うのですが、未だ存在チェックに暗黙カーソルのCOUNTを使う人がいます。
若者ならまだしも、そこそこの単価をもらっているベテランプログラマでも、こんな書き方をする人がいます。
SELECT COUNT(*) INTO ln_count FROM tab_a; -- IF ln_count = 0 THEN dbms_output.put_line('ERROR!'); RAISE NO_DATA_FOUND; END IF;
もう少し凝ったモノだと、カーソル中に
SELECT DECODE(COUNT(*), 0, TRUE, FALSE) FROM tab_a;
みたいな・・・(実際にはもっと複雑なSQLですが)
このテーブルtab_aが数件しか無ければ大きな影響は無いかもしれませんが、億単位のデータを保持していたらどうなるでしょう。
処理性能に影響が出るのは言うまでも無いですよね。
では、どう書くのが良いのか。
DECLARE CURSOR c1 IS SELECT 1 FROM tab_a; ln_check NUMBER; BEGIN OPEN c1; FETCH c1 INTO ln_check; IF c1%NOTFOUND THEN dbms_output.put_line('ERROR!'); RAISE NO_DATA_FOUND; END IF; CLOSE C1; : END;
と書きます。
こうすることで、テーブルtab_aに何件入っていようと、1件分のデータにしかアクセスしないようになります。
よく、
: SELECT COUNT(*) INTO ln_count FROM tab_a WHERE ROWNUM = 1; --←ここを追加 -- IF ln_count = 0 THEN dbms_output.put_line('ERROR!'); RAISE NO_DATA_FOUND; END IF; :
でも良いのでは?と言われますが、あまり推奨したくはありません。
「データが存在するか」というロジックなのですから、素直に「存在するか」というロジックを書くことが、より可読性を向上させると思います。
「データが存在するか」というロジックに対し「件数をカウントする」は、間にワンステップ思考が入っています。よりシンプルな思考を求めるのであれば、COUNTの使用は避けた方が良いと思います。
ま、ここはムキになって否定するほどのポイントではないので、現場で見かけてもとやかく言うことはありませんが。
いずれにしても、存在チェックを行う際はデータアクセスを最小限に留めることが重要です。
ディスカッション
コメント一覧
まだ、コメントがありません