23

私はテーブルを持っています:

-- Tag

ID  | Name
-----------
1   | c#
2   | linq
3   | entity-framework

次のメソッドを持つクラスがあります。

IEnumerable<Tag> GetAll();
IEnumerable<Tag> GetByName();

この場合、コンパイル済みクエリを使用する必要がありますか?

static readonly Func<Entities, IEnumerable<Tag>> AllTags =
    CompiledQuery.Compile<Entities, IEnumerable<Tag>>
    (
        e => e.Tags
    );

次に、私のGetByName方法は次のようになります。

IEnumerable<Tag> GetByName(string name)
{
    using (var db = new Entities())
    {
        return AllTags(db).Where(t => t.Name.Contains(name)).ToList();
    }
}

コードを生成しSELECT ID, Name FROM Tagて実行Whereします。CompiledQueryそれともこの場合は避けるべきですか?

基本的に、コンパイル済みクエリをいつ使用する必要があるかを知りたいです。また、Web サイトでは、アプリケーション全体に対して 1 回だけコンパイルされますか?

4

5 に答える 5

33

次のすべてに該当する場合は、a を使用する必要CompiledQueryがあります。

  • クエリは、パラメーター値のみが変化して、複数回実行されます。
  • クエリが複雑で、式の評価とビューの生成のコストが「かなり」(試行錯誤)
  • IEnumerable<T>.Contains()では動作しないような LINQ 機能を使用していませんCompiledQuery
  • 可能であれば、クエリは既に簡略化されているため、パフォーマンスが大幅に向上します。
  • クエリ結果をさらに構成するつもりはありません (restrict または project など)。これにより、結果が "逆コンパイル" されます。

CompiledQueryクエリが最初に実行されたときに機能します。最初の実行には何のメリットもありません。他のパフォーマンス チューニングと同様に、実際のパフォーマンスのホットスポットを修正していることを確認するまでは、通常は避けてください。

2012 Update: EF 5 はこれを自動的に行います (「Entity Framework 5: 自動クエリ コンパイルの制御」を参照)。したがって、上記のリストに「EF 5 を使用していません」を追加します。

于 2011-02-08T17:34:05.880 に答える
6

コンパイルされたクエリは、式ツリーの生成に費やされる時間を節約します。クエリが頻繁に使用され、コンパイルされたクエリを保存する場合は、必ずそれを使用する必要があります。クエリの解析に、データベースへの実際のラウンドトリップよりも時間がかかる場合が多くありました。

あなたの場合、大文字と小文字を区別せSELECT ID, Name FROM Tagずに生成されることが確実な場合(関数が返され、実際のクエリは呼び出し後にのみ実行されるため、WHERE疑わしいです)、使用しないでください。AllQueriesIQueryableToList

すでに述べたように、大きなテーブルでSELECT * FROM [someBigTable]は非常に時間がかかり、クライアント側でのフィルタリングにさらに多くの時間を費やします。したがって、コンパイルされたクエリを使用しているかどうかに関係なく、フィルタリングがデータベース側で行われることを確認する必要があります。

于 2011-02-08T12:38:49.760 に答える
1

コンパイルされたクエリは、クエリを再利用しながら式ツリーを何度も構築するよりもパフォーマンスを向上させるために、複雑なクエリと言う大きな式ツリーを持つ linq クエリでより役立ちます。あなたの場合、私はそれがほとんど時間を節約すると思います。

于 2011-02-08T11:56:17.393 に答える
1

コンパイル済みクエリは、アプリケーションのコンパイル時にコンパイルされます。クエリを頻繁に再利用したり、クエリが複雑になったりするたびに、コンパイル済みクエリを試して実行を高速化する必要があります。

ただし、記述するコードが少し多くなり、単純なクエリの場合は価値がない可能性があるため、すべてのクエリでそれを使用するわけではありません。

ただし、最大のパフォーマンスを得るには、データベース サーバーですべての処理を行うストアド プロシージャも評価する必要があります。Linq が可能な限り多くの作業をデータベースにプッシュしようとしても、ストアド プロシージャの方が高速になる状況が発生します。

于 2011-02-08T12:14:07.020 に答える
0

コンパイルされたクエリはパフォーマンスを向上させますが、それほど大きくはありません。複雑なクエリがある場合は、可能であればストアド プロシージャまたはビューを使用することをお勧めします。データベースに任せた方が良いかもしれません。

于 2011-02-08T12:10:41.617 に答える