実現したいこと
VBAを使用し、DBからデータを取得して、エクセルに貼り付けたいです。
RecordSetからエクセルに貼り付ける処理に時間がかかりすぎて困っています。
どのようにしたら高速化できますか。
前提
DB : SQLserver
データ数:15列3000行程度
今の処理時間:90秒
目標の処理時間:10秒
SQL文の処理時間は問題ないです。
再計算や描画はオフにしてます。
試したこと
VBA
1Dim SQL As String 2Dim rst As Recordset 3 4Set rst = DB.getRecordSet(SQL) 5Call Range("A1").CopyFromRecordset(rst) 6 7Public Function getRecordSet( _ 8 OpenSQL As String, _ 9 Optional CursorType As ADODB.CursorTypeEnum = ADODB.CursorTypeEnum.adOpenKeyset, _ 10 Optional LockType As ADODB.LockTypeEnum = ADODB.LockTypeEnum.adLockReadOnly _ 11 ) As ADODB.Recordset 12 Set getRecordSet = New ADODB.Recordset 13 getRecordSet.Open OpenSQL, conn, CursorType, LockType 14End Function
「RecordSetからエクセルに貼り付ける処理に時間がかかりすぎ」
「SQL文の処理時間は問題ないです。」という根拠は?
15列3000行程度でCopyFromRecordsetにそんなに時間がかかるとは思えないです。
Set rst = DB.getRecordSet(SQL)
と
Call Range("A1").CopyFromRecordset(rst)
のそれぞれの処理時間は計測しましたか。
計測方法は下記を参考に。
https://www.limecode.jp/entry/speed/timer-measure-processtime
回答ありがとうございます。計測すると
Set rst = DB.getRecordSet(SQL) 0.5秒
Call Range("A1").CopyFromRecordset(rst) 72秒
という結果になりました。
データのシートへの貼り付け自体はそれほど時間がかかるとは考えにくいです。
RecordSet.Open だけでは、まだレコードセットにデータを読み込んでいません。
CopyFromRecordset するときにレコードセットにデータを読み込んで、貼り付けている推測されます。
そのレコードセットにデータを読み込むのに時間がかかっているのかな、という気がします
SQLではなく、15列3000行程度のテーブルを作成してそれを読み込んで貼り付けた場合の時間も計測してみてください。
計測しました。
RecordSet → テーブル 0.1秒
テーブル → RecordSet 0.6秒
ご指摘どおり、データの貼り付け自体は時間はかかりません。
SQL、テーブルの設計に原因があるということになりますね。
その設計を見直しましょう。
SQL自体はDB管理ツールで問題ないことを確認しています。
他を調べた結果、adOpenKeysetが原因でした。
adOpenKeysetを使うと、キーがレコード内を移動するために処理が遅くなることがわかりました。
今回はテーブルをそのまま貼り付けるだけなので、adOpenKeysetは不要なため不使用にしたところ、高速化が実現できました。
ご相談にのっていただきありがとうございました。
回答1件
あなたの回答
tips
プレビュー