質問: context.QueryMultiple(string.Join(" ; ", selectCommands)); return queries.Select(q => grid.Read()).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()).AsList();` すべての結果セットは同じ`type T` 、取得している最終結果は`List>`と仮定します。 次のように`Async-Await`を使ってクエリを変更することができます。 ``` var grid = await context.QueryMultipleAsync(string.Join(";",selectCommands)); return queries.Select(q => await grid.ReadAsync()).AsList(); ``` > これは助けになりますか? > > 限られた範囲で、操作を非同期にすることによって、しかし利点は限られたものになるでしょう。 クエリの主要部分 > この場合、QueryMultipleの実行には約3秒かかり(これはSQL上でのほぼ実行時間です)、2つのクエリを持つグリッドの読み取りには最初に3秒かかり、次に9秒かかります。 > > これは驚くべきことです、Readはここで行われる唯一の操作です、queryはすでに実行されています。 `DataReader`を使用しています。これは既に接続されています。これは、 `DataReader`ラッパーであるDapper `GridReader`と同じ`DataReader` 。 50Kレコードだけでも読み取りに時間がかかる場合は、ネットワークIOの速度など、影響を与える他のパラメータを見つけ出すことをお勧めします。これは、メモリ/ RAMの制限に当たるため、大きな影響を与える外部要因です。 > これは、Dapperが最初にクエリを実行するためだけにデータベースをクエリするためです。次に、読み取り要求に応じてデータベースに再度接続し、特定の読み取りに関するすべてのデータを取得します。 > > 以下の理由により、常により良い戦略です。 1. 高度にスケーラブルなアプローチ 2. データベースは、設計したものに対して、複数のクエリをまとめて実行できます。 3. 順次収集/結果読み取りなし これを言っても、50Kレコードを読むだけでは非常に遅く、外部要因にならなければならないことに私はまだ驚いています。バッファ設定を切り替えても50Kレコードだけには大きな影響はありません。バイナリシリアライゼーションを使用して適切に圧縮されています。通常はバッファオンが最適化設定として推奨されます。 編集1 `QueryMultiple`を使用してもDapperはすでに最適化されているため、ハードウェアの変更が改善をもたらすかどうかを理解するために、まず比較的ハイエンドのハードウェア、RAM、プロセッサ、ネットワークIOで同じテストケースを実行します`QueryMultiple` `GridReader`を介して`GridReader`