社内SEの徒然なる日記

NetCOBOLからのSQLチューニング

実行計画が変な気がする

とあるSQLがsqlDeveloperとかで手動実行すると数秒程度で終わるのに、NetCOBOLから実行すると1時間以上かかる、という事象がありました。

どうやら、NetCOBOLからだと実行計画が奇妙な作られ方をするようです。
別段、複雑なSQLなわけじゃないんですけどねねぇ。

※ ちなみにDBはOracleです。

とりあえず、NetCOBOLのSQLにヒント句を追加して実行計画を固定することにしたんですけど、これが意外と手こずりました。

チューニング(間違い)

とりあえず、ヒント句を追加してみました。

サンプルはこんな感じ。
TESTDBテーブルをインデックス「INDEX_TEST01」を使用して検索するようにヒント句を追加します。

SELECT

/*+
INDEX(TESTDB, INDEX_TEST01)
*/

FROM
TESTDB,
ARUFU
WHERE TESTDB.AB = '1'
AND TESTDB.TE = '0'
AND ARUFU.TTT = TESTDB.TTT


事前に、sqlDeveloperでヒント句が機能していることを確認してから、ソースをコンパイル&リリース。
そして再実行したんですけど、一向に終わる気配がない。
...あれ?

チューニング(正解)

なんかスペルミスでもしたかと、冷や汗をかきながらヒント句の書式を確認したところ、ヒント句の記述にテーブルとインデックスの間にあったカンマが余計なことが分りました。

× : INDEX(TESTDB, INDEX_TEST01)
○ : INDEX(TESTDB INDEX_TEST01)

修正後のソースはこれ。

SELECT

/*+
INDEX(TESTDB INDEX_TEST01)
*/

FROM
TESTDB,
ARUFU
WHERE TESTDB.AB = '1'
AND TESTDB.TE = '0'
AND ARUFU.TTT = TESTDB.TTT


もう一度コンパイルして再実行したところ、きちんと動きました。

考察

どうやら、NetCOBOLでヒント句を指定する場合、書式を正しく守らないといけないようです。
困ったことに、他のシステム(sqlDeveloperとか)では間違えた方のヒント句でも機能するんで、この件があるまでずっと勘違いしていました。
いやいや、お恥ずかしい。

それにしても、NetCOBOLから実行したSQLの実行計画の作られ方は気になるところですね。
プリコンパイラで奇妙な編集でもしてるのかと思いもしたんですけど、最終的にはOracle側で実行計画を作るわけだし、変な動きをさせる方が難しい気がするんですけどね。

ヒントになりそうなのが、他のシステムでは機能したヒント句が、NetCOBOLでは機能しないということでしょうか?
今までは、プリコンパイラはSQLの書式チェック位しかしていないと思っていたのですが、もしかすると実行計画に影響を与えるような妙な編集とかしてるのかもしれないですね。

まぁ、NetCOBOL(というよりPro*COBOLか?)の内部動作なので、これ以上の調査は難しいんですけど...

とりあえず、変に動かれても困るので、NetCOBOLからSQLを実行する時は必ずヒント句を付けるようにしました。
「何のためのコストベースオプティマイザだ?」と思わない訳じゃないですけどね。
スポンサードリンク

PageTop

コメント


管理者にだけ表示を許可する