
抽出件数の取得方法
oo4oに限った話ではないでしょうが、SELECT文を実行する時には件数も一緒に取得したいものです。
マニュアルによると、RecordCountプロパティを使用する方法と、SnapshotIDを使用してカウント文を発行する2通りの手法があるようです。
ただし、マニュアルによるとRecordCountプロパティは、「Oracleから結果の表全体をただちにフェッチする必要....」云々ってことで性能問題が発生するかもしれないから使わないでねって書いてます。
ふーむ、気になるんで試してみましょうか。
実験してみた
1.関数の修正
前回(oo4oでExcelから接続してみた(抽出))作った、SELECT文を実行するoracleSqlSelect関数に、RecordCountプロパティを使用した件数取得と、デバッグログの出力を追加します。
こんな感じですね。
'OraDynasetオブジェクトの作成
Debug.Print Date & " " & Time & " SQL実行 start ---"
Set myDynaset = OraDatabase.CreateDynaset(pSql, ORADYN_READONLY)
Debug.Print Date & " " & Time & " SQL実行 end ---"
'スナップショットIDを取得
Set mySnapshotID = myDynaset.Snapshot
'RecordCountプロパティの値(件数)を取得
Debug.Print Date & " " & Time & " RecordCount start ---"
Debug.Print "myDynaset.RecordCount = " & myDynaset.RecordCount
Debug.Print Date & " " & Time & " RecordCount end ---"
'検索時のスナップショットIDから、カウントを実行
Debug.Print Date & " " & Time & " SQL(カウント) start ---"
Set myOraDynCount = OraDatabase.CreateDynaset("select count(*) NUMROWS FROM (" & pSql & ")", 0&, mySnapshotID)
Debug.Print Date & " " & Time & " SQL(カウント) end ---"
'レコード件数を共通変数に格納します。
OraRecodeCount = myOraDynCount.Fields("NUMROWS").Value
Debug.Print "OraRecodeCount = " & OraRecodeCount
2.結果件数の少ない場合のテスト
実行時間が10秒程度で、件数が数万件程度になるSQLを作って実行しています。
ちなみに、取得するITEMFはVARCHAR2型で8BYTEの項目です。
SELECT ITEMF FROM ABCD WHERE TTDATE >= '20120401'
実行結果はこんな感じです。
結果が約8万件として、RecordCountプロパティの取得に3秒、カウントの実行で9秒ですね。
やはり、カウントの実行時に時間を食ってますね。

3.結果件数の多い場合のテスト
先ほどのSQLからWhere句を除いて、ABCDテーブルの全件を取得します。
SELECT ITEMF FROM ABCD'
今度の実行結果は、下記の通りになりました。
抽出件数が約345万件として、RecordCountプロパティの取得に172秒、カウントの実行で9秒ですね。
やはり、件数が多くなるとRecordCountプロパティの取得には時間がかかりますね。

考察
大体は当初の想定通りで「抽出件数が少なければ、RecordCountプロパティの取得速度は速い」となりました。
しかし、これってどんな状況で使えるだろう?
例えば「実行に異様に時間が掛かる。SQLチューニングの余地は無い。処理時間は短くないとダメ。件数は数万件程度で収まる」という条件で、時間短縮のためにカウントの実行時間を削りたい、とか?
...すでに、この状況自体が異様ですよね。
どうやら、素直にSnapshotIDを使用してカウントを実行させた方が良いようですね。
前回:oo4oでExcelから接続してみた(抽出)
次回:oo4oでExcelから登録してみた(ExecuteSQL)
投稿記事の一覧:目次
--- blog end ---
スポンサードリンク


