2011-10-17 35 views
0

私はそれが3秒に1秒から取るrs.Open上のSQL Server 2008VBA:より高速なレコードセットの接続

Dim cnn As Object 
Dim rs As Object 
Dim strSQL As String 

Set cnn = CreateObject("ADODB.Connection") 'ADO Connection 
cnn.ConnectionString = "DRIVER=SQL Server;SERVER=" & dbServer & ";" & _ 
          "Trusted_Connection=Yes;DATABASE=" & dbDatabase 
cnn.Open 

strSQL = "Select * from mytable" 

Set rs = CreateObject("ADODB.Recordset") 
rs.Open strSQL, cnn, adOpenKeyset, adLockOptimistic 

からレコードにアクセスするために、次のコードを持っています。レコードセットにアクセスするより速い方法がありますか?

変数dbServerとdbDatabaseは、モジュール内で定数文字列として定義されています。

+1

レコードセットを開く前に接続を試してください。時間がかかっているのですか、それともクエリが実行されていますか? –

+0

どのように2つのコマンドを分けることができますか? – Rick

+0

私はあなたの質問を完全に読まなかったと思います。**あなたはすでに** cnn.Open **との接続を開いています。この場合、それは問題のクエリに時間がかかるようです。そして、HansUpの提案。いくつかの詳細を追加することも役に立ちます。あなたが取り戻しているデータセットの量はどれくらいですか? –

答えて

3

あなたは2つの操作している:

  1. オープン接続
  2. オープンレコードセットは、その接続遅延がある

を使用していますか?

Debug.Print Now()の行を2つのopen文の直前に追加し、もう1つをレコードセットを開いた後に追加することができます。

接続を開くときにボトルネックが発生する場合は、ネイティブクライアントプロバイダを使用することで処理速度が向上するかどうかを確認してください。 www.connectionstrings.com: SQL Server Native Client 10.0 OLE DB Provider

レコードセットを開くことがボトルネックである場合は、いくつかの選択肢があります。実際に動的/編集可能なレコードセットが必要ない場合は、adOpenKeysetの代わりにadOpenStaticを使用してください。すべてを返すSELECTステートメントを使用する代わりに、CommandTypeEnum adCmdTableを使用してテーブルを開くことができます。または、SELECTステートメントでは、「*」の代わりに明示的なフィールドリストを含める必要があります。 (それはおそらく大きなボトルネックではありませんが)また、主キー値に基づいて単一のレコードを選択するためにWHERE句を試すこともできます。

3

mytableがVIEWではなく基本表であると仮定すると、SQLは可能な限り簡単です。つまり、最適化の有効範囲はありません。

VBAコードでさらにRBAR(行を嫌う行=敬称)処理を行う場合は、より複雑なSQLを使用して手続き型ロジックを「セットベース」のパラダイムとして書き直すことを検討してください。 WHERE句を追加するとよいでしょう。

テーブル全体の内容を上書きする必要があり、テーブルが比較的大きい場合は、比較的長い時間がかかります。ここでも最適化のためのコードの範囲はありません。

現在、同期フェッチを実行しています。つまり、VBAコードの実行は、フェッチが完了するまでrs.Open行まで待機します。ユーザーにとっての効果は、アプリケーションがフリーズしている可能性があり、クラッシュする可能性があります。

別の方法として、非同期フェッチを使用する方法があります。コードクラスモジュールを再配置し、レコードセットをWIthEvents(モジュールレベルに再配置する必要がある)として宣言し、レコードセットを開く前にadAsyncFetchオプションを指定します(これに対応するには、アプローチを少し変更する必要があります)。これにより、要求が送信されるとすぐに実行がrs.Openを超えて続行されます(したがって、接続/レコードセットを閉じるコードを別のサブプロシージャに再配置する必要があります)。 FetchProgressFetchCompleteイベントを使用して、アプリケーションのエンドユーザーにフィードバックを与えることができます。詳細はthis MSDN articleを参照してください。

私は、アクセスエンジン/プロバイダーから意味のある「完了した」スタイルの進捗状況を得ることはできませんでした。しかし、少なくともマーキースタイルのプログレスバーを表示して、データが取得されていることをユーザーに安心感を与えることができます。ユーザーはUI(コントロールをクリックするなど)とやりとりでき、アプリケーションがクラッシュしていないことを確認できます。

関連する問題