12

LINQtoSQLクエリの高速化に焦点を当てた記事を参照していました。言及されている手法の1つは、「コンパイル済みクエリの使用」であり、その使用方法を説明しています。

コンパイルされたクエリのパフォーマンスの向上を見たかったので、作成者が提供したのと同じ例を試しました。NorthwindDbをデータコンテキストとして使用しました。通常の実行とcompiledqueryの実行を試し、LINQPADで確認しました。

まず、 CompileQueryを使用せずにクエリを実行してみました。2.065秒かかりました。

var oo =   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 100)
   select o;

oo.Dump ("Order items with unit price more than $100");

var oo1 = from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 10)
   select o;

oo1.Dump ("Order items with unit price more than $10"); 

次に、CompileQueryを使用したクエリ。2.100秒かかりました。

var oo = CompiledQuery.Compile ((TypedDataContext dc, decimal unitPrice) =>    
   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > unitPrice)
   select o
);

oo (this, 100).Dump ("Order items with unit price more than $100");
oo (this, 10).Dump ("Order items with unit price more than $10");

それらを数回再実行すると、両方のアプローチにかかる時間はほぼ同じであることがわかりました。

ここでは、メソッドごとに2つのクエリ実行のみが表示されます。それぞれに10個のクエリを作成してみました。しかし、両方とも約7秒で完了しました。

クエリを事前にコンパイルすると、パフォーマンスが本当に向上しますか?それとも、使用条件を間違えていますか?

あなたの時間と配慮していただきありがとうございます。

編集:受け入れられた回答を読んだ後、読者は、コンパイルされたクエリがパフォーマンスをどのように改善するかをうまく説明しているこの記事 も読みたいと思うかもしれません。

4

1 に答える 1

11

LINQ クエリには、特にコストがかかる可能性がある主な部分が 2 つあります。

  1. LINQ 式を SQL ステートメントにコンパイルします。
  2. SQL ステートメントを実行して結果を取得する

あなたの場合、比較的単純なクエリと、非常に遅いデータベース接続、非常に大きなデータセット、またはこの特定のクエリを実行するための最適な方法でインデックスが作成されていないテーブルがあります。または、3 つすべての組み合わせかもしれません。

そのため、クエリの SQL を生成するのにかかる時間 (おそらく 10 ~ 50 ミリ秒) と比較すると、2 番目のステップには非常に長い時間 (約 1000 ミリ秒) がかかっているため、違いはほとんどわかりません。

次の条件がすべて当てはまる場合、大幅な改善が見られます。

  1. LINQ クエリが複雑で、
  2. データベースへの高速接続があり、
  3. SQL クエリ自体はそのデータベースですばやく実行されます。
  4. 結果セットは十分に小さいため、データベースから比較的迅速に転送されます。

実際には、コンパイルに 500 ミリ秒以上かかるクエリがありますが、実際の実行には数ミリ秒しかかかりません。これらは通常、クエリのプリコンパイルに重点を置いているケースです。

プリコンパイルされたクエリから期待できるパフォーマンスの向上を事前に知る良い方法の 1 つは、オブジェクトを使用してクエリの2 番目のインスタンスの時間Stopwatchを計り、LINQPad の Analyze SQL 機能を使用して生成された SQL を直接実行することです。SQL クエリがすぐに返されるが、LINQ クエリに時間がかかる場合は、プリコンパイルすることをお勧めします。

于 2012-04-05T04:32:08.983 に答える