6

200,000レコードのテーブルがあり、使用しているトップ10のみ.Take()を取得していますが、データを取得するのに約10秒かかります。

私の質問は、この.Take()メソッドはデータベースからすべてのデータを取得し、クライアント側で上位10個をフィルタリングするかどうかです。

これが私のコードです:

mylist = (from mytable in db.spdata().OrderByDescending(f => f.Weight)
                                    group feed by mytable.id into g
                                    select g.FirstOrDefault()).Take(10).ToList();

spdata()ストアドプロシージャからインポートする関数です。

ありがとう

4

4 に答える 4

9

ストアドプロシージャは、おそらく非常に遅い大量のデータをクライアントに返します。クエリをsprocにリモート接続することはできません。これは、ビューまたはテーブル値関数を使用して可能になります。

クエリでsprocを使用する方法はありません。単独でのみ実行できます。

あなたの意図はおそらくTake(10)サーバー上で実行することでした。これを機能させるには、インラインクエリ、ビュー、またはTVFに切り替える必要があります。

于 2012-12-18T13:42:13.320 に答える
7

拡張メソッドは、データベースからすべての結果をフェッチするわけでTakeはありません。それはどのようにTake機能するかではありません。

ただし、db.spdata()呼び出しはおそらくすべての行をフェッチします。

于 2012-12-18T13:41:54.983 に答える
1

100%確信はありませんが、覚えているように、EFDataContextを使用してSPを呼び出すとIEnumerableの結果が得られます...

パフォーマンスを最適化するためのいくつかの方法があります。

  • 検索条件をSPパラメータとして渡し、ストアドプロシージャでフィルタリングを実行します。

または、SPに非常に単純なクエリがあり、変数を宣言しておらず、いくつかのテーブルを結合している場合は、次のようになります。

  • 必要なクエリを指定するインデックス付きビューを作成し、そのビューでTakeメソッドを呼び出します。
    これはあなたに何を与えるでしょうか?作成したビューにマップすると、EFはIEnumerableではなくIQueryableの結果を返すようになります。これにより、SQLコマンドが最適化され、すべてのデータを受信して​​から、必要な10個の要素を取得すると、10個の要素を取得するだけのSQLコマンドが形成されます。

また、IEnumerableとIQueryableの違いを確認することをお勧めします。

于 2012-12-18T13:50:03.920 に答える
0

これは、グループ化する前にデータを並べ替えているためです。これはSQLでは実行できません。

集計を使用して各グループから最大の重みを取得してから、重みを並べ替えて最大の10個を取得する必要があります。

mylist = (
  from mytable in db.spdata()
  group feed by mytable.id into g
  select g.Max(f => f.Weight)
).OrderByDescending(w => w).Take(10).ToList();
于 2012-12-18T14:05:09.133 に答える