- PR -

DataGridViewのレスポンスについて

1
投稿者投稿内容
つぼ
会議室デビュー日: 2003/07/30
投稿数: 3
投稿日時: 2007-06-21 20:05
初めての投稿になります。
初心者ですがよろしくお願いします。

現在、Windowsフォームを作成しています。
(VisualStudio2005(C#))

検索フォームを作成し、指定した条件をもとにDB(AccessMDB)を検索し、
検索結果をDataGridViewに表示するといったものです。
検索SQLは副問い合わせ等をつかった複雑なSQLです。(ここは変えられません)

なお、DataGridViewに表示する項目数は3項目で合計120byte程になります。

MDBへはADO.NETで接続し以下のようにSQLを実行しています。

-------------------------------------------------------
// パラメータのSQLでインスタンスを初期化
OleDbCommand cmd = new OleDbCommand(iSQLStr, dbconn);

// SQL実行
OleDbDataReader dr = cmd.ExecuteReader();
-------------------------------------------------------

上記で取得した検索結果を以下のようにDataGridViewに設定しています。

-------------------------------------------------------
// 検索結果が0件の場合、ダイアログ表示して終了
if (!dr.HasRows)
{
return;
}

// 検索結果を画面表示する
int idx = 0;
while (dr.Read())
{
listKeyValue.RowCount++;

listKeyValue[0, idx].Value = dr["key_val_disp"].ToString();
listKeyValue[1, idx].Value = dr["key_val"].ToString();
listKeyValue[2, idx].Value = dr["key_code"].ToString();
idx++;
}
-------------------------------------------------------

上記で3万件前後の取得結果を表示しようとすると、
表示するまでに10数分時間がかかってしまいます。
(検証マシンスペック CPU:Pentium4 3.20GH Memory:512MB)

ちなみに、HashTableに格納したデータを同じように
DataGridViewに設定しても4〜5分ほどかかりました。

レスポンスを向上する上でのアドバイス等いただければ幸いです。
よろしくお願いします。
よっし〜。
ベテラン
会議室デビュー日: 2007/04/17
投稿数: 89
お住まい・勤務地: 北のほうの国
投稿日時: 2007-06-21 20:22
表示させるだけだったらDataReaderを使わずに
単純にバインドさせればいいのではないでしょうか。


かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-06-21 21:41
3万行も表示しても誰もみないんじゃ。。。

とりあえず、どこに時間がかかっているのか計測してみてはどうでしょうか?
Debug.WriteLine(DateTime.Now.ToString())
を要所要所に入れてみる。

listKeyValue はどんな型の変数ですか?
って、もしかして DataGridView ?
DataSource を設定してバインドしましょう。
_________________
かるあ のメモスニペット
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2007-06-21 22:51
仮想モードにすれば最初に表示されるまでの時間は短くなるとも思いますが、あれはあれで大量のイベントをうまくさばかないともっさりしてしまいます。
抽出されたデータを見るだけなら ListView の仮想モードという手もありそうです。
DataGridView よりも仮想モードの実装は簡単です。

かるあさんも仰っておられますが、
3万件のデータを全て表示する必要はあるのでしょうか。
目視で3万件というのはあまり現実的ではないと思います。
Google などの検索のように一定件数ごとに表示するという手もありますよね。
high4
会議室デビュー日: 2005/08/23
投稿数: 7
投稿日時: 2007-06-21 23:08
一般的に予測できない量(又は大量)のレコードをグリッド形式に読み込むとき、読み込み量の単位を分割制御することを考えます。
分割制御には2通り考えられ、1つは超過分を要求時に処理するもの、もう1つはバックグランドで行います。
dotNetの場合、System.ComponentModel.BackgroundWorker があるので後者のほうが楽です。
最初に500レコード読み込みグリッドに追加します。
そこで return してユーザーに制御を戻します。
その際、EOFで無ければ、BackgroundWorker をスタートさせ残りを500づつ処理させます。BackgroundWorker とその作成元は連絡しあって画面のコントロールのEnable/Disableを制御してユーザーを誘導します。
( 私は MS の DataGridView を使っていないので、一般論としてのコメントです )

KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-06-22 09:20
どうしても3万件を一度に表示する必要があるのなら、
DataReader を使うよりもバインドしたほうがまだいいと思います。

この辺りはもう目を通されていますか?

Windows フォーム DataGridView コントロールでのパフォーマンス チューニング


ですが、私もみなさんもおっしゃっているように、
3万件を一度に表示する必要があるのかが疑問です。
そもそも、何を目的としている画面なのでしょうか?

データの編集・更新が目的の画面であれば、
例えば画面上部にドロップダウンリストとかを配置して、
区分なりの条件で絞り込んでから表示するようにする手もありますし、
その方がユーザーにとっても使いやすいと思います。
つぼ
会議室デビュー日: 2003/07/30
投稿数: 3
投稿日時: 2007-06-22 09:54
数々のアドバイスありがとうございます。

皆さんのアドバイスをもとにKIさんにご紹介いただいた
サイトを確認しましたら、皆さんのアドバイスに関する
情報がいろいろと記載されていました。

まずは皆さんのアドバイスにありました様々な方式をもとに
何がベストかを検証させていただきます。

なお、皆さんの疑問にありました3万件を一度に表示する意味ですが、
私自身もその必要はないと思います。
検索結果一覧に3万件表示しても実際その中から選択したい情報を
見つけるというのは無謀というものです。

実際、KIさんのご提案にもありましたが、
画面上部に検索条件を用意し、絞り込みをする機能はありますので、
通常の運用の中では、条件部にて絞り込みを行うのが前提なのですが、
とは言え、絞り込みを行わなくても検索できる機能であるため、
その際に大量データを表示するためのレスポンスを懸念していました。

現在検討しているのは先頭の数千件だけを(1〜2秒で)表示し、
絞り込みを促すようなダイアログを表示するようにしようとしています。

今回皆さんにアドバイスを求めさせていただいたのは、
大量データを扱う画面ということもあり、
レスポンスが思うように上がらなかったために
レスポンスを意識した開発手法をご教示いただければと思ったのが経緯です。

検証次第、また結果を詳細にご報告させていただきます。
つぼ
会議室デビュー日: 2003/07/30
投稿数: 3
投稿日時: 2007-06-22 13:48
皆さんからのアドバイスやご紹介いただいたサイトを参考にし、
まずはバインド方式で検証してみました。

DataReaderを使わずにDataAdapterを用いてSQLを実行し
DataTableに格納した上でDataGridViewに設定しました。

結果は、SQL実行終了後からDataGridViewに設定するまでの時間が
3万件のデータ表示で「20msec」まで短縮されました。
無謀な検索で7万件表示も試みましたが、40msecという結果でした。
今までの7〜12分が嘘のような結果でした。

期待値以上の成果になりましたので、
今回はバインド方式で製造を進めることにします。
(実際に3万件表示させるかどうかは別にして・・・。)

その他、皆さんからのご提案はまた機会を見つけて検証させていただき、
都度ご報告させていただこうと思います。

この度は本当にありがとうございました。
大変、勉強になりました。
1

スキルアップ/キャリアアップ(JOB@IT)