PL/SQL等のバッチ処理でたまに見かける最悪なプログラム 
シェア
DB更新などのバッチ処理で Pro*C 使ってたり PL/SQL 使ってたりするプロジェクトは結構多いが、あほかっ!と思ってしまうことがある。ソースが汚いとか main() や BEGIN END の間に全部の処理書いてるとか、そういうのはまだ我慢できる(ていうか、全部直してる訳にはいかないので)。では、何が気に食わないのかと言うとループ中にファイルにアクセスする感覚で SELECT 句発行してたりするプログラムが結構多いこと。
ちょっと考えればわかるだろう!とか、仕様はどうなってんだ!とか、ソースレビューの段階で気づかないか?とか色々意見はあるだろうが、ちょっと大きめのプロジェクトなどでコーディングを丸投げしたり、プロジェクトに火がついてプログラマ大量投入して解決、みたいなところでは結構見かけてきた。んで、「バッチ処理が遅い」だとか「バッチ処理が重い」だとか言ってるんだが、当たり前だろう!
例えば、具体的にどんなプログラムかっつーと
DECLARE count number; CURSOR cur IS SELECT id FROM TRAN; BEGIN FOR c IN cur LOOP -- マスタの値を取得 SELECT * FROM MASTER WHERE id = c.id; -- なんかの処理 -- -- 存在チェック SELECT COUNT(*) INTO count FROM TRAN2; IF (count = 0) THEN -- insert 処理 ELSE -- update 処理 END IF; END LOOP; END;
みたいな。
これでカーソルが数万とかの単位になるとそれだけで重くなるし、他にもカーソルの値で他のテーブル検索して 1ループ 1秒前後かかるとしたら、単純計算で 1秒 * 1万回。普通に2~3時間くらいかかったり。Join しとけよ!
つーか、大体 COBOL上がりの設計者で、PL/SQL 使ってバッチ作ろうって人に多いんだが(偏見です)、更新を行単位で処理しようとするんだな。どうしても必要な時は FETCH すりゃーいいけども、大抵の場合集合的に更新かけれるし、ムリならワークテーブルなりで対象データ絞れよな。Insert/Update 1万回するのと、1万行の更新を1回するのとの考え方の違いをわかってないっつーか。
まぁ、俺がこんなに怒ってるのは、今まさにそんなプログラムをメンテしたりしてるからであり、このめんどくせーって思いと怒りをどこかの誰かと共有するために書いてる訳だが、こういうプログラム見たことない?
「見たこと無い!」って言うあなたは、幸せモノです!
シェア

よくありますね。
最近はmerge文でselect/insert/updateの同時実行がお気に入りです。
oracleバージョン古くないのでしょうか?
なんとも判別しがたいです。