DOBON.NETプログラミング道掲示板

■35451 / 親記事)  DataGridViewのVirtualModeを有効した場合の実装方法
  
□投稿者/ 炎の妖精さん 一般人(27回)-(2023/06/12(Mon) 13:30:32)
  • アイコン環境/言語:[Win10/VB.NET/Framework3.5/VS2010] 
    分類:[.NET] 

    お世話になり、いつも助けていただき感謝です。
    此度の件もお付き合いいただければ恐縮です。

    DataGridViewに約50〜1000万件のデータを表示させたいと考えており、
    DataTableに膨大なデータを挿入して、DataGridViewのDataSourceを設定すると"system.outofmemoryexception"のエラーが発生します。
    ネットで調べると仮想モード(VirtualMode)を有効にするとメモリ使用量を抑えることが出来るとの記載があった為、試しに実装しました。
    ●技術レポート「DataGridViewコントロールのVirtualMode(仮想モード)について」
    https://www.softech.co.jp/mm_200506_tr.htm

    今回はデータを表示させたいだけであり、新規行や削除、値の変更は全くありませんので"DataGridView.CellValueNeeded"のみの実装で良いかなと思いましたので
    実装したのですが、状況は変わらずメモリ不足のエラーが発生しました。

    どのように実装すればメモリ消費を抑えるコードが書けるのでしょうか?
    恐縮ですが、何卒よろしくお願いいたします。
マルチポストを報告
違反を報告
引用返信 削除キー/
■35453 / ResNo.1)  Re[1]: DataGridViewのVirtualModeを有効した場合の実装方法
□投稿者/ 魔界の仮面弁士 大御所(1553回)-(2023/06/12(Mon) 16:00:50)
  • アイコン
    No35451に返信(炎の妖精さんさんの記事)
    > DataGridViewに約50〜1000万件のデータを表示させたいと考えており、
    仮に 1 レコード当たり 32 バイト程度のデータであったとしても、
    1000万レコードあったら、300MB 級のデータサイズになりますね。

    これらが Web Service として通信される場合、JSON や XML 化のために
    さらに数倍のデータ量が要求されることになるかもしれません。


    > ネットで調べると仮想モード(VirtualMode)を有効にするとメモリ使用量を抑えることが出来るとの記載があった為、試しに実装しました。
    どのように実装しましたか。
    実際に試せるような実験コードが提示されていないので、
    以下、概要のみの回答となりますが:


    > DataTableに膨大なデータを挿入して、DataGridViewのDataSourceを設定すると"system.outofmemoryexception"のエラーが発生します。
    DataGridView の仮想モードであれ、ListView の仮想モードであれ、
    そもそも 1000万件のデータを画面に表示して、そのすべてをスクロールして
    その 1件 1件をすべて閲覧するという事は非常に稀であり、
    実際に必要なデータはごく一部だけであろうかと思います。

    なので仮想モードにおいては、「現在見えているページ」、「スクロールで要求されたページ」のための
    必要最小限の小さなデータを、必要に応じてサーバーから動的に読み込むという実装をとります。
    Google Map で地図をスクロールするたびに Web 通信が行われる状況に似ていますね。

    一度読み込んだデータでも、別の領域をロードしたらまた忘れられてしまうので、
    以前の情報をとっておきたい場合は、独自のキャッシュ処理を追加します。
    (いずれにしても、大量データを保持し過ぎることが無いような設計が求められます)
    https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/virtual-mode-with-just-in-time-data-loading-in-the-datagrid?view=netframeworkdesktop-4.8
違反を報告
引用返信 削除キー/
■35454 / ResNo.2)  Re[2]: DataGridViewのVirtualModeを有効した場合の実装方法
□投稿者/ 魔界の仮面弁士 大御所(1554回)-(2023/06/12(Mon) 16:11:32)
  • アイコンNo35453に追記(魔界の仮面弁士の記事)
    > (いずれにしても、大量データを保持し過ぎることが無いような設計が求められます)
    > https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/virtual-mode-with-just-in-time-data-loading-in-the-datagrid?view=netframeworkdesktop-4.8


    上記サンプルの場合、表示領域に合わせて、

    Select Top 【rowsPerPage】列1, 列2, 列3, …
    From テーブル名
    Where ソート条件列 NOT IN
    (
     Select Top 【lowerPageBoundary】 ソート条件列
     From テーブル名
     Order By ソート条件列
    )
    Order By ソート条件列

    という SQL Server への問い合わせが行われる想定ですね。
違反を報告
引用返信 削除キー/
■35455 / ResNo.3)  Re[3]: DataGridViewのVirtualModeを有効した場合の実装方法
□投稿者/ 魔界の仮面弁士 大御所(1555回)-(2023/06/12(Mon) 19:00:19)
  • アイコンNo35454に追記(魔界の仮面弁士の記事)
    > 上記サンプルの場合、表示領域に合わせて、
    > という SQL Server への問い合わせが行われる想定ですね。

    SQL Server 2012 以降や Oracle12c以降であれば、
    ORDER BY 句 で OFFSET と FETCH を使うことでページングできます。
    https://sql55.com/query/paging-query-results.php

    ページ指定での分割読取り手法は、お使いのデータベースによって
    使用可能な構文も異なるでしょうし、そこは随時調整してください。
違反を報告
引用返信 削除キー/
■35457 / ResNo.4)  Re[4]: DataGridViewのVirtualModeを有効した場合の実装方法
□投稿者/ 炎の妖精さん 一般人(28回)-(2023/06/13(Tue) 11:18:22)
  • アイコン魔界の仮面弁士様
    いつも助けていただきまして、ありがとうございます。

    > ■No35454に追記(魔界の仮面弁士の記事)
    >> 上記サンプルの場合、表示領域に合わせて、
    >> という SQL Server への問い合わせが行われる想定ですね。
    >
    > SQL Server 2012 以降や Oracle12c以降であれば、
    > ORDER BY 句 で OFFSET と FETCH を使うことでページングできます。
    > https://sql55.com/query/paging-query-results.php
    >
    > ページ指定での分割読取り手法は、お使いのデータベースによって
    > 使用可能な構文も異なるでしょうし、そこは随時調整してください。

    イメージとしましてはECサイトの検索画面のような感じでしょうか?
    1ページで20,30件を表示させ、ページ送りが出来るようなイメージです。

    その手法をとるなら、やりたいことが実現できるかも知れません。
    一度、検討させていただきます。

解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -