2017-07-20 6 views
0

移行を実行していて、SQLサーバーからデータを取得しようとしたときにパフォーマンスが低下することがありました。私のやり方は次のとおりです。SQLクエリでOutOfMemoryExceptionが発生し、SQL Serverから大量のデータが取得される

ctx.ExampleEntity.Database.SQLQuery<ClassConverter>("Select....") 

ClassConverterExampleEntityとは関係を持たないクラスです。問題は、そのクエリから1.5百万以上のレコードが取得され、リストを作成しようとするとOutOfMemoryExceptionがスローされ、それを回避できないということです。

これはEF 6.0です。

///////////////////////////////////ソリューション

まゆからの回答後、私はこのコードを書いていますが、1Mでは例外がスローされません。 sqlは最終的なDBにないレコードを返します。

List<ClassConverter> listRowsToInsert = new List<ClassConverter>(); 
int countRecords=-1; 
int skipCount = 0; 
while(countRecords!=0){ 
    List<ClassConverter> listIndivInsert = genEntitAgp.Database.SqlQuery<ClassConverter>(File.ReadAllText("sql/limitPfm.sql")).Skip(skipCount).Take(1000000).ToList(); 
    countRecords = listIndivInsert.Count(); 
    listRowsToInsert.AddRange(listIndivInsert); 
    if (countRecords < 1000000) 
     countRecords = 0; 
    skipCount += 1000000; 
} 

すべて

+0

一度に何百万ものレコードが本当に必要ですか? – mason

+0

コールをバッチに分割しますか? –

+0

リレーションがない場合、クロスジョインが返される可能性があります。つまり、1つのテーブルのすべてのローが2番目のテーブルのすべてのローに関連付けられていることを意味します。各テーブルに1000行がある場合、1,000,000行が返されます。任意の種類の結合を行っておらず、表の行数が150万にすぎない場合は、遅延フェッチまたはバッチでフェッチするか、フィルタリングする必要があります。 – pmbAustin

答えて

0

ため

おかげで、あなたはエンティティをマッピングし、その後db.Records.Skip(n).Take(m)でバッチでそれらを処理することができEF 6.0を使用している場合は?

+0

それは動作します! ) – kartGIS

+1

この単純なページネーションには1つの欠点しかありません。データが変更された場合、重複したレコードまたは不足しているレコードを取得することができます。 –

関連する問題