C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 大量データを格納したDataSetのコピーについて


(過去ログ 19 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■7492 / inTopicNo.1)  大量データを格納したDataSetのコピーについて
  
□投稿者/ アリパパ (1回)-(2007/09/06(Thu) 23:10:03)

分類:[.NET 全般] 

初めての書き込みになります。皆様、よろしくお願いします。

開発環境:VisualStudio2005 開発言語:C#&ADO.NET OS:WinXP Pro

現在、FormにDataGridViewを貼り付け、DataSetをバインディングした簡易データベースのようなアプリを
作成しております。機能的にはフィールドの追加・削除等も出来るようになっており、この操作を行う際に
は、メインのFormにて、DataSetのコピーを作成後、フィールド操作用のダイアログにこのコピーを渡して、
そのダイアログにて、渡されたDataSetのコピーを操作して、DataColumnの登録・削除を行うというフロー
をとっています。なおDataSetのコピーは、DataSet.Copy()にて行っています。
※フィールド操作用ダイアログがOKで終了した場合、コピー作成されたDataSetをメインのDataSetとして更新

このフローを実行中に、問題が発生してしまいました。DataSetの持つレコードやフィールド数が多い場合、
DataSet.Copy()の実行に非常に時間がかかるのです。ちなみにレコード数:30000、フィールド数:128で計
測してみたのですが、50秒近くかかりました。アプリの仕様としてはレコード数の上限は60000、フィール
ド数の上限は256とする予定なのですが、これではお話にならないレベルです。
※DataSetの容量が大きくなると、DataGridViewの動作も非常に遅くなり、これにも困っているのですが・・・

他に方法はないものかと探してみたのですが、なかなか情報が得られませんでした。現状の状態ではアプリ
として使い物にならず、非常に困っております。回避方法又は高速化の方法をご存じの方がおられましたら、
些細な事でも助かりますので、ご教授頂けないでしょうか。

宜しくお願い致します。
引用返信 編集キー/
■7493 / inTopicNo.2)  Re[1]: 大量データを格納したDataSetのコピーについて
□投稿者/ れい (116回)-(2007/09/06(Thu) 23:36:04)
No7492 (アリパパ さん) に返信
> このフローを実行中に、問題が発生してしまいました。DataSetの持つレコードやフィールド数が多い場合、
> DataSet.Copy()の実行に非常に時間がかかるのです。ちなみにレコード数:30000、フィールド数:128で計
> 測してみたのですが、50秒近くかかりました。アプリの仕様としてはレコード数の上限は60000、フィール
> ド数の上限は256とする予定なのですが、これではお話にならないレベルです。
> ※DataSetの容量が大きくなると、DataGridViewの動作も非常に遅くなり、これにも困っているのですが・・・
>
> 他に方法はないものかと探してみたのですが、なかなか情報が得られませんでした。現状の状態ではアプリ
> として使い物にならず、非常に困っております。回避方法又は高速化の方法をご存じの方がおられましたら、
> 些細な事でも助かりますので、ご教授頂けないでしょうか。
>

たくさんのレコード全てを同時に表示する必要は無いですよね?
そんなに画面は大きくないですし。

ですので、たくさんある場合は部分的に取得します。
そうすればDataSet.CopyもDataGridViewも早く動作できますから。

引用返信 編集キー/
■7494 / inTopicNo.3)  Re[2]: 大量データを格納したDataSetのコピーについて
□投稿者/ アリパパ (2回)-(2007/09/07(Fri) 00:45:35)
No7493 (れい さん) に返信

れい様、早速の回答、ありがとうございます。

> たくさんのレコード全てを同時に表示する必要は無いですよね?
> そんなに画面は大きくないですし。
>
> ですので、たくさんある場合は部分的に取得します。
> そうすればDataSet.CopyもDataGridViewも早く動作できますから。

なるほど、部分的に取得するという方法があるのですね。
現在はBindingNavigatorのDataSourceにDataSetをセットしているのですが、
例えばこの際に、DataSetの一部をセットするというイメージでしょうか?
なお気になるのはDataGridViewにてスクロールがされた場合は、どのように
対応するのかという点です。不勉強で申し訳ありません。

またDataSet.Copyの件ですが、フィールド操作画面にて、データ型の変更機
能があり、データ型が変更された場合は、データを変換する必要があるため、
メイン画面にて持つDataSetの全データをコピーしてフィールド操作画面に
渡す必要があり、この部分は部分的に対応出来ないのです。うーん。。。

引用返信 編集キー/
■7495 / inTopicNo.4)  Re[3]: 大量データを格納したDataSetのコピーについて
□投稿者/ れい (117回)-(2007/09/07(Fri) 02:47:19)
No7494 (アリパパ さん) に返信
> ■No7493 (れい さん) に返信
> なるほど、部分的に取得するという方法があるのですね。
> 現在はBindingNavigatorのDataSourceにDataSetをセットしているのですが、
> 例えばこの際に、DataSetの一部をセットするというイメージでしょうか?

> なお気になるのはDataGridViewにてスクロールがされた場合は、どのように
> 対応するのかという点です。不勉強で申し訳ありません。

レコード数10、フィールド数10とかなら、適当なコードで何も考えなくても動きますが、
「レコード数の上限は60000、フィールド数の上限は256とする予定」なのですよね?
1フィールド1byteを無駄なく保存したとしても、1x256x60000 byte = 15.36Mbyteです。
実際に必要とされるメモリは数倍〜数十倍になるでしょう。

これは現在のPCや.Netでは無造作に扱っていい量ではありません。
無駄な操作のないコードにする必要があります。

使わない情報をADO.Netから取るのは無駄です。
「見える分+少し」だけ取得するようにします。

スクロールされ、持って無いデータを取得する必要があるなら、
その分だけ追加で取得します。

これにはDataGridViewのVirtualModeを使うといいでしょう。

> またDataSet.Copyの件ですが、フィールド操作画面にて、データ型の変更機
> 能があり、データ型が変更された場合は、データを変換する必要があるため、
> メイン画面にて持つDataSetの全データをコピーしてフィールド操作画面に
> 渡す必要があり、この部分は部分的に対応出来ないのです。うーん。。。

いいえ。できるはずです。
フィールド操作画面に、DataSet取得元のTableの情報を渡しておけば、
データ型を変更する必要が出たときだけ、データを取得し、変更できます。

せっかくADO.Netを使っているのに、
一度に大量のデータを取得し、全データをオンメモリで操作する、
なんていうのは無駄で危険です。
それに、アリパパさんの言うような操作がすばやくできるなら、
そもそもデータベースなんて要らないことになってしまいます。

量を扱う部分はデータベースにまかせ、
コードでは表示や操作に専念するよう、
設計を見直したほうがいいです。
引用返信 編集キー/
■7498 / inTopicNo.5)  Re[4]: 大量データを格納したDataSetのコピーについて
□投稿者/ アリパパ (3回)-(2007/09/07(Fri) 10:16:25)
れい様、ご教授ありがとうございます。

> 使わない情報をADO.Netから取るのは無駄です。
> 「見える分+少し」だけ取得するようにします。
>
> スクロールされ、持って無いデータを取得する必要があるなら、
> その分だけ追加で取得します。
>
> これにはDataGridViewのVirtualModeを使うといいでしょう。

有難うございます。早速調べてみました。MSDNにVirtualModeの実装サンプルがありました。
なかなか難しそうですが、このサンプルを参考にトライしてみます。

> いいえ。できるはずです。
> フィールド操作画面に、DataSet取得元のTableの情報を渡しておけば、
> データ型を変更する必要が出たときだけ、データを取得し、変更できます。
>
> せっかくADO.Netを使っているのに、
> 一度に大量のデータを取得し、全データをオンメモリで操作する、
> なんていうのは無駄で危険です。
> それに、アリパパさんの言うような操作がすばやくできるなら、
> そもそもデータベースなんて要らないことになってしまいます。
>
> 量を扱う部分はデータベースにまかせ、
> コードでは表示や操作に専念するよう、
> 設計を見直したほうがいいです。

おっしゃる通りですね。
フィールド操作画面起動時は、Table情報のみを受け渡し、データ型変更が行われた際に、
メイン画面からデータを取得するイベントを設け対処したいと思います。

貴重なご指摘、感謝致します。
引用返信 編集キー/
■7706 / inTopicNo.6)  Re[5]: 大量データを格納したDataSetのコピーについて
□投稿者/ アリパパ (4回)-(2007/09/13(Thu) 13:18:24)
れい様、先日はご教授ありがとうございました。

その後、DataGridViewのVirtualモードの実装にトライしてみましたら、
何とか動くレベルになりました。やはり大量レコード扱い時のパフォーマンスは格段
に進歩しました。

ただこの実装に伴い、問題が出てしまいました。
以前はDataSetをBindingNavigatorにセットし、BindingNavigatorのBindingSourceを
DataGridViewのDataSourceとしてセットしておりました。そのため、BindingNavigator
とDataGridViewのカレントの動きは同期が取れていました。
Virtualモード実装後は、DataGridViewのDataSourceには何もセットしておりません。
その為、BindingNavigatorでのカレントレコード移動リクエストがあった際に、Data
GridViewのカレントセルを移動する必要があるのですが、bindingNavigatorPositionItem_TextChanged
関数にて、DataGridViewのカレントセルを移動させようとすると、「SetCurrentCellAddressCore
関数への再入呼び出しを生じるため、この操作は有効ではありません。」という例外
が発生してしまい、回避方法が不明です。

何か回避方法はありませんでしょうか。
ご教授頂けますと幸いです。宜しくお願い致します。



引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -