4

データベース内の製品を介して製品を検索する必要があり、これを正しい方法で設定して、行数が多い (1,000,000) 場合に安定したパフォーマンスが得られるようにしたいと考えています。私は LINQ と EF の経験はある程度ありますが、検索アルゴリズムを書いたことがなく、次のコードを取得しましたが、いくつかの疑問が残ります。

context.products.Where(i => i.Name.ToLower().Contains(searchText.ToLower());

説明も検索する必要があります。

context.products.Where(i => i.Description.ToLower().Contains(searchText.ToLower());
  1. このコンテキストでは.ToLower()パフォーマンスが低下しますか?

  2. 説明に定期的なインデックスがNameありFullTextますか? これは適切で、通常のインデックスは でうまく機能し.contains()ますか?

  3. LINQ またはその他の方法を使用する必要がありますか?

  4. 検索テキストが名前/説明に出現する回数を取得できる方法はありますか?

ありがとうございました

4

3 に答える 3

1

私の場合、ストアド プロシージャは使いたくありませんでした。私はEntity Frameworkを使用していましたが、それが私が使いたかったものです!

この方法が役立つかどうかを確認してください。

    public static IQueryable<T> LikeOr<T>(this IQueryable<T> source, string columnName, string searchTerm)
    {
        IEnumerable<string> words =
            searchTerm.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries).Where(x => x.Length > 1);

        var sb = new StringBuilder();
        for (int i = 0; i < words.Count(); i++)
        {
            if (i != 0)
                sb.Append(" || ");

            sb.Append(string.Format("{0}.Contains(@{1})", columnName, i));
        }

        return source.Where(sb.ToString(), words.ToArray());
    }

上記のすべてのメソッドは、SQL 文字列を構築し、それを Dynamic LINQ Where メソッドに渡します。大まかに言うと、これにより、クエリ全体を SQL で記述するのではなく、必要な場所でのみ直接 sql を使用できるようになります。次のようなもので呼び出されます。

    public List<Book> SearchForBooks(string phrase)
    {
        return _db.Books.Include(x=> x.Images).LikeOr("Title", phrase).OrderBy(x => x.Title)
            .Take(6).Select(x => x).ToList()
            .OrderByCountDescending("Title", phrase);
    }

これは、Microsoft によって作成された動的 LINQ dll によって可能になりましたが、フレームワークには含まれていません。動的 LINQこれにより、一部の領域でより柔軟になることができます。

于 2013-03-28T21:50:37.557 に答える
1
  1. パフォーマンスに大きな影響を与えるため、これより低い値は使用しないでください。
    次のいずれかを使用します。

    StringComparison.OrdinalIgnoreCase
    StringComparison.CurrentCultureIgnoreCase

  2. '%text%' のように変換される contains を使用しているため、SQL サーバーがインデックスを使用する可能性は低いです。全文検索を実装する場合は、ストアド プロシージャを使用して全文検索の利点を利用する必要があります。

  3. Linq は、手書きの SQL ステートメントよりも常に低速です。dapper.net Web サイトでいくつかのパフォーマンス メトリックを見てきました

一般に、最新のエンティティ フレームワークを使用している場合は、バージョン 5 でパフォーマンスが大幅に改善されているため、かなり良いパフォーマンスが得られるはずです。

于 2013-03-28T21:40:19.360 に答える
1

これを行うストアド プロシージャを作成するか、DbContext を使用して生の SQL を作成することを真剣に検討しSqlQueryます。もし私がこのコードを書いていたら、それが私がすることです。私にとっては、EntityFramework と performanceant が実際に組み合わされることはありませんでした。

于 2013-03-28T21:42:47.017 に答える