私はこれについて多くの質問を受けました、そしてなぜ彼がdapperの上で複数のグリッドを使い続けたくないのかについてのMarc Gravellの説明を見ました。
しかし、私はただ何かを理解したいのです
var grid = context.QueryMultiple(string.Join(" ; ", selectCommands));
return queries.Select(q => grid.Read<T>()).AsList();
この場合、QueryMultipleの実行には約3秒かかり(これはSQL上でのほぼ実行時間です)、2つのクエリを持つグリッドの読み取りには最初に3秒かかり、次に9秒かかります。
それぞれがおよそ50k行あり、そのうち2列がint、2倍精度(sqlではfloat)、および日時である5列のみです。バッファリングをオフにしようとしましたが、役に立ちませんでした。
これは、Dapperが最初にクエリを実行するためだけにデータベースをクエリするためです。次に、読み取り要求に応じてデータベースに再度接続し、特定の読み取りに関するすべてのデータを取得します。
それぞれ1つのクエリと一緒に実行されるいくつかの非同期タスクを作成するだけでよいのでしょうか。
私はこれについて多くの質問を見ました、そして、なぜ彼がdapperの上で複数のグリッドを使い続けたくないのかについてのMarc Gravellの説明
最も可能性の高い理由は、 MARS - Multiple Active Result Sets
を使用して複数の結果を生成するクエリを実行していますが、それでもすべての結果セットに一度にアクセスできないことです。 DataReader
NextResult
機能を使用して内部的に実行されるため、これらは順番に読み取ることができます。アプリケーションにとってそれはまだ1つの呼び出しです、理想的には複数のAsync呼び出しを使用して同じことが常に並列にすべての結果セットを取得するとき(理想的なシステム/リソース使用量)
あなたの質問に関して:
queries.Select(q => grid.Read<T>()).AsList();
すべての結果セットは同じtype T
、取得している最終結果はList<IEnumerable<T>>
と仮定します。
次のようにAsync-Await
を使ってクエリを変更することができます。
var grid = await context.QueryMultipleAsync(string.Join(";",selectCommands));
return queries.Select(q => await grid.ReadAsync<T>()).AsList();
これは助けになりますか?
限られた範囲で、操作を非同期にすることによって、しかし利点は限られたものになるでしょう。
クエリの主要部分
この場合、QueryMultipleの実行には約3秒かかり(これはSQL上でのほぼ実行時間です)、2つのクエリを持つグリッドの読み取りには最初に3秒かかり、次に9秒かかります。
これは驚くべきことです、Readはここで行われる唯一の操作です、queryはすでに実行されています。 DataReader
を使用しています。これは既に接続されています。これは、 DataReader
ラッパーであるDapper GridReader
と同じDataReader
。 50Kレコードだけでも読み取りに時間がかかる場合は、ネットワークIOの速度など、影響を与える他のパラメータを見つけ出すことをお勧めします。これは、メモリ/ RAMの制限に当たるため、大きな影響を与える外部要因です。
これは、Dapperが最初にクエリを実行するためだけにデータベースをクエリするためです。次に、読み取り要求に応じてデータベースに再度接続し、特定の読み取りに関するすべてのデータを取得します。
以下の理由により、常により良い戦略です。
これを言っても、50Kレコードを読むだけでは非常に遅く、外部要因にならなければならないことに私はまだ驚いています。バッファ設定を切り替えても50Kレコードだけには大きな影響はありません。バイナリシリアライゼーションを使用して適切に圧縮されています。通常はバッファオンが最適化設定として推奨されます。
QueryMultiple
を使用してもDapperはすでに最適化されているため、ハードウェアの変更が改善をもたらすかどうかを理解するために、まず比較的ハイエンドのハードウェア、RAM、プロセッサ、ネットワークIOで同じテストケースを実行しますQueryMultiple
GridReader
を介してGridReader