2

10,000 から 20,000 の一意のフィルターを、8 つの列と適切なインデックスを使用して 50M 行のデータセットに適用する必要があります。

私の現在のアプローチは、これらのクエリを一度に 1 つずつ動的に生成して実行することです。

var stats = (from a in db.AggregatedStats
             where a.StatType.StartsWith("TOTAL_ITEM")
             select a);

// Add more filters to the WHERE clause

foreach (var stat in stats) { // Process the data }

この方法は、SQL Server から MoveNext() へのデータの "ストリーミング" と呼ばれていると思います。

データをプログラムのメモリにバッファリングする方が効率的でしょうか?

var stats = (from a in db.AggregatedStats
             where a.StatType.StartsWith("TOTAL_ITEM")
             select a).ToList();

次に、代わりにこのエンティティのリストにフィルターを適用します。

var result = (from a in stats
              where a.Region.Equals(region)
              select a);

これにより、SQL Server クエリの数が 10,000 から 1 に効果的に減少します。

この場合、データセットをプログラムにバッファリングすることは、10,000 クエリからデータをストリーミングするのにかかる時間と比較して、追加の RAM に値するでしょうか?

ありがとう!

4

2 に答える 2

2

これらのフィルターを分析し、どのフィルターがほとんどのデータを除外しているかを確認するのに時間がかかります。データの 95% を除外するフィルターが 10 ~ 20 個あることがわかるでしょう。

ほとんどのデータを除外する上位 X フィルターを特定できる場合は、それらのフィルターを使用してクエリをデータベースに適用するだけです。結果として得られるのは、メモリ内でバッファリングしたり、さらにフィルタリングしたりできる限定されたレコードのセットです。

于 2013-03-26T11:32:11.620 に答える
2

ネガティブ。データベースからの列挙を可能な限り最後の 1 秒まで延期すると、無効化されるデータがメモリにプッシュされるのを防ぐことができます (これにより、このアプリケーションに使用されるメモリが膨張するだけです)。これは、現在のサンプルが使用しているアプローチであり (開始するまで実際には呼び出されforeachないため)、最もパフォーマンスが高いはずです。

混乱していると思います。あなたが書くとき

var stats = (from a in db.AggregatedStats
         where a.StatType.StartsWith("TOTAL_ITEM")
         select a);

実際には何も起こらなかった -statsデータを取得する方法を知っている反復子が含まれているだけで、ToList()そのクエリを で呼び出すか列挙するまでforeach、実際には何も要求されないため、パフォーマンスが得られます。

于 2013-03-25T22:06:47.327 に答える