3

特定のデータセットに対してユーザーが定義した列から個別の値を取得するクエリを作成する必要があります。数百万の行が存在する可能性があるため、ステートメントは可能な限り効率的である必要があります。以下は私が持っているコードです。

このLINQクエリの順序は何ですか?これを行うためのより効率的な方法はありますか?

var MyValues = from r in MyDataTable.AsEnumerable()
               orderby r.Field<double>(_varName)
               select r.Field<double>(_varName); 

IEnumerable result= MyValues.Distinct();
4

4 に答える 4

6

AsEnumerable()通話やフィールド変換についてはあまり話せませんが、LINQ側の場合、これorderbyは安定したクイックソートであり、そうする必要がありますO(n log n)。私が推測しなければならなかったとしても、それ以外はすべてそうあるorderbyべきなO(n)ので、全体としてはまだですO(n log n)

更新:LINQDistinct()呼び出しもである必要がありますO(n)

したがって、全体として、このことのBig-OhはまだO(Kn log n)です。ここで、Kは一定です。

于 2012-10-01T20:58:35.793 に答える
1

これを行うためのより効率的な方法はありますか?

MyDataTable後でメモリで並べ替える代わりに、初期化するクエリの一部として並べ替えを行うと、効率が向上する可能性があります。

于 2012-10-01T21:02:19.117 に答える
1

コメントから

私は実際にMyDistinct.Distinct()を使用しています

個別の_varName値が必要で、dbmsのselectクエリでこれをすべて実行できない場合(最も効率的な方法)、Distinct前にを使用する必要がありますOrderBy。ここでは順序が重要です。

重複を除外する前に、数百万行すべてを注文する必要があります。最初にdistinctを使用する場合は、残りのみを注文する必要があります。

var values = from r in MyDataTable.AsEnumerable()
             select r.Field<double>(_varName);
IEnumerable<double> orderedDistinctValues = values.Distinct()
                                                  .OrderBy(d => d);

私は最近、E.Lippertが注文が重要な場合とそうでない場合に良い説明で答えた関連する質問をしました:

LINQ拡張メソッドの順序はパフォーマンスに影響しませんか?

これは、順序が重要であることがわかる小さなデモですが、CPUの場合、doubleの比較は簡単なので、実際には重要ではないこともわかります。

Time for first orderby then distinct: 00:00:00.0045379
Time for first distinct then orderby: 00:00:00.0013316
于 2012-10-01T21:10:20.190 に答える
0

上記のクエリ(linq)は、100万レコードすべてが必要で、64ビットメモリアドレス指定OSに十分なメモリがある場合に適してます。

クエリの順序は、基になるコマンドが表示された場合、次のように変換されます。

Select <_varname> from MyDataTable order by <_varname>

これは、データベースIDEまたはコマンドラインで実行した場合と同じくらい優れています。

パフォーマンスに関する簡単な回答を提供します

  1. 可能であればwhere句を挿入します(インデックスが付けられた列を使用)
  2. ユーザーがインデックス付けされた列(_varname)を選択できることを確認してください。DBがインデックス付けされていない列で100万件のレコードを並べ替えようとしていると想像してください。これは明らかに遅いですが、linqがbadpressを受け取る危険があります。
  3. MyDataTableの初期化が(可能であれば)価値のあるレコードで正しく行われていることを確認します(これもwhere句に基づいています)
  4. 基になるクエリのプロファイルを作成し、
  5. 可能であれば、storedprocsを作成します(議論の余地があります)。Storedprocsを含むエンティティモデルを作成することもできます

今日は高速かもしれませんが、テーブルスペースが大きくなり、データが順序付けられていない(インデックスが付けられていない)と、処理が遅くなります(適切なlinq式があったとしても)

お役に立てれば

そうは言っても、データベースが適切にインデックス付けされていない場合、つまり

于 2012-10-01T21:14:27.690 に答える