質問

DataGridViewにロードしたい大きなデータセット(100,000を超えるレコード)があります。これを行うストアドプロシージャは、完了するまでに10秒以上かかる場合があります。

これまでのところ、UIのロックを防ぐBackgroundWorkerがあり、初歩的な「お待ちください」ダイアログを実装しています。

私がやりたいのは、何らかの形でデータベースから返された結果をDataGridViewに入力することです。 SQL Server Management Studioがそれをどのように記述するかが、クエリを実行すると、クエリがまだ実行されていてもすぐに行が返ってくるのが最良の方法です。クエリを停止し、返された行を保持するボタンもあります。

自分のコードでこれを行うにはどうすればよいですか

DataGridViewはデータの行を表示するためにのみ使用され、ユーザーはそれをクリックして別の操作を行います。データベースには何も書き戻されません。

役に立ちましたか?

解決

データグリッドビューで100,000行ですか? 「いいえ」と言うだけです!

  1. ユーザーは一度に100,000行を表示できません
  2. 100,000行を送信するネットワークトラフィックは重要ではありません
  3. 100,000のdatagridview行のメモリオーバーヘッドは重要ではありません
  4. ユーザーは1行だけを選択して続行する必要があります
  5. このアプリが一度に複数のユーザーによって使用された場合、DBAはあなたを追い詰めます

オースティンのアドバイスに従い、一度に1ページのみを表示します

他のヒント

最良のオプションは、何らかのページングメカニズムを使用することであるように思われるため、一度に一定量のデータのみをユーザーに表示します。これにより、データの取得とページの読み込みが高速化されます。 GridViewの組み込みページングを使用できます(レコードのページのみを表示する場合でも、データセット全体を毎回プルするため、このアプローチでは.NETキャッシュを使用することをお勧めします)。また、LINQ to SQLでページを一度に取得するだけでページングを実装することもできます。以下は、最近見つけた良い方法へのリンクで、その方法を説明しています。

http://www.dbtutorials.com/display /linq-to-sql-paging-cs.aspx

他の人が提案したように、グリッドに10万件のレコードを表示するのは悪い考えのように聞こえますが、本当に必要な場合は...

バックグラウンドワーカースレッドは順調に進んでいますが、データリーダーを使用して、返される行を順番に読み取る必要があります。バックグラウンドワーカースレッドは、データリーダーから読み取られるすべての行について、UIスレッドへのグリッド行の追加をマーシャリングする必要があります。

UIの応答性を維持するために別のスレッドを使用する利点は、とにかく常に行を追加するのに忙しいため無効になります。何らかのバッチ処理アプローチを実装し、UIに1秒に1回程度だけ新しい行を追加することを提案します。ここでは細心の注意を払い、起こりうる競合状態に留意する必要があります。バックグラウンドワーカーがデータリーダーからある種のコレクションに行を追加する状況が発生する可能性があり、UIがコレクションを同時に読み取りたい場合があります-これはほぼ確実に問題になります。

Management Studioと同じ方法でDataGridViewで実行できるとは思わない。ストアドプロシージャの呼び出しが完了すると、アプリのすべての行を一度に取得できます。

同様に、バックエンドのチューニングも検討できます。このような場合にインデックスを追加すると、何度も役に立ちました。 "実行計画"を使用して、SQL Server Management Studioからストアドプロシージャを実行してみてください。オプションが有効。ストアドプロシージャが行き詰まっている可能性のある場所(つまり、実行率が高い場所)を探します。アイテムの上にマウスを移動すると、実行の詳細のリストが表示されます。リストの下部で、比較されているフィールドがあるかどうかを確認します。これらは、インデックス作成候補者にとっては死に物です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top