質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

19460閲覧

SQL実行時に「メモリが不足しています。」と表示される。

yuki00079

総合スコア45

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2016/12/26 11:40

###前提・実現したいこと
タイトル通りですが、作成しているアプリケーションからSQLを実行すると下記の例外が発生してしまいます。
SQLが悪いのか、アプリ実装時の問題なのか原因がわからず困っております。

###発生している問題・エラーメッセージ

System.OutOfMemoryException メモリが不足しております。

###該当のソースコード

Private Async Function GetData() As Task(Of DataTable) Dim dataTable = New DataTable() Using con As New SqlConnection(strConnection) Using cmd As New SqlCommand("SQL"), con) With {.Connection = con} Await con.OpenAsync().ConfigureAwait(False) Using da = Await cmd.ExecuteReaderAsync().ConfigureAwait(False) DataTable.Load(da) Return dataTable End Using End Using End Using End Function

###試したこと
実行するSQLをSSMSで実行すると問題なく実行されます。(約200万レコード,30秒ほど。)
時期を指定し、その期間のクエリを発行するのですが期間が長くなると上記の例外が発生してしまいます。
非同期での取得方法に誤りがあるのか、それとも単純にDataTableの限界なのか原因を把握できておりません。
他の方法での取得方法はございますでしょうか。

###補足情報(言語/FW/ツール等のバージョンなど)
.net4.5
SQLServer2014 standard

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

質問のコードでは、SQLで読みだされた全データがメモリ上の変数dataTableに格納されます。
コードを実行するプロセスが使えるメモリ量よりも、dataTableを大きくしようとすると System.OutOfMemoryExceptionが発生します。

プロセスが使えるメモリ量を増やす事で解決する可能性があります。具体的には、仮想メモリのサイズ(ページファイルのサイズ)を大きくします。

プロセスが使えるメモリの上限(32bitのWindowsでは4GB)に達していてSystem.OutOfMemoryExceptionになっている場合には、仮想メモリの設定では解決できません。

投稿2016/12/27 02:00

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki00079

2016/12/27 05:17

返信ありがとうございます。 >仮想メモリのサイズ 簡易的なアプリケーションなのでそこまで膨大なメモリを使用することを想定しておりませんでした。上記の例外が発生する際には1GB近くのメモリを消費していたのでそれが原因のようですね。
guest

0

ベストアンサー

DataTableはとても重たいので200万レコードも入れたら、OutOfMemoryExceptionを起こさなかったとしても使い物にならないと思います。
快適なアプリケーションを作るためには、一度に扱うのは1万レコード未満にすることをお勧めします。

投稿2016/12/27 04:14

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki00079

2016/12/27 05:15

返信ありがとうございます。 >DataTableはとても重たいので のようですね。代わりのものというのはあるのでしょうか。List? >一度に扱うのは1万レコード未満に SQL側で件数を1万件に抑えることはできますが、1万以降のレコードを表示する際にはどのようにすればよいのでしょうか。 GridViewのようなコントロールに表示させられる限界なのか。それとも万以上のレコードを表示するようなアプリから見直すべきなのか。
hihijiji

2016/12/27 06:37

1万って書いたのは上限で、GridViewで表示するなら100件ぐらいにしていおたほうが良いかとおもいます。 >代わりのものというのはあるのでしょうか。List? はい。重さと扱いやすさのバランスで List<T> は、いい選択だと思います。 >SQL側で件数を1万件に抑えることはできますが、1万以降のレコードを表示する際にはどのようにすればよいのでしょうか。 データ自体に指標となるものがある場合はそれで、無い場合はプライマリーキーに対してシーケンシャル番号を振る位しかないでしょうね。
hihijiji

2016/12/27 07:13

このサイト例では、トップページの新着タブを開いたときは20件ほどしか表示してませんよね。 続きを見たい場合は「▽もっと見る」を押すようになってます。 一度に表示する件数を増やしても、見づらくなってユーザにとってのメリットは殆どありません。 詳しくは「画面のページング」などで検索してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問