2017-05-07 9 views
0

は、私は〜500000のLINQと.Count大きなデータベース

私は唯一の10項目を示して個々の列フィルタ、と私のフロントエンドにのDataTableを追加した大きなMySQLデータベースからデータを取得し、ASP MVCプロジェクトを作成します。

enter image description here

data = dc.books.OrderBy(x => x.id).Where(x => 
     (market_id == 0 || x.market_id == market_id) 
     && (name == null || x.name != null && (x.name.Contains(name))) 
     && (author == null || x.author != null && (x.author.Contains(author))) 
    ).Skip(param.Start).Take(10).ToList(); 

仕事速いと良いです。

私は怒りのためのフィルターの後にカウントを追加しようとします。サーバーMySQLのタイムアウトエラーを仕事や

非常にゆっくりと

count = db.books.Count(x => 
        (market_id == 0 || x.market_id != 0 && x.market_id == market_id) 
        && (name == null || x.name != null && (x.name.StartsWith(name))) 
を動作しないのはなぜ数えるので、ゆっくりと仕事をしたりしませんか?

すべてのコードの私conttoller here

+0

Sql Serverは、(述語も含む)非常に高速になる傾向があります。カウントが高速であるかどうかにかかわらず、おそらくデータベースエンジンに深く根ざしているでしょう。私はMySqlについて知らないが、あなたはいくつかの重要なインデックスを欠いていると思う。 –

答えて

0

のようにあなたはこれをやったほうが良いです、どんな違いが発生したSQLにあります場合は、OR式の部分を分離するために、括弧を追加するかどうかを確認することがあります:

var query = db.books.AsQueryable(); 

if (market_id!=0) 
    query = query.Where(x=>x.market_id==market_id); 

if (name!=null) 
    query = query.Where(x=>x.name.StartsWith(name)); 

count = query.Count(); 
data = query 
    .OrderBy(x=>x.id) 
    .Skip(param.Start) 
    .Take(10) 
    .ToList(); 

ないすべてのLINQは、プロバイダは、フィルタを最適化するのに非常に優れており、それらをデータベースに渡します。多くのデータベースでは、これらのタイプのクエリに対してひどいクエリプランが生成され、最悪のケースのクエリプランが生成され、そのように見えるすべてのクエリに対して再利用されるため、通常はインデックスを使用する可能性がなくなります。上記のコードを使用してください。多くのケースで

、あなたも、あなたがこれを行うだろうので、回数を制限する場合があります「1000の以上の結果の」カウント== 1001は、メッセージを使用した場合、その後

count = query.Take(1001).Count(); 

0

これは、すべてのデータベースがどのように動作するかに尽きるとSQLの種類は、最終的に生成されます。 StartsWithはワイルドカード検索に変換されます。ワイルドカード検索は単純なクエリより時間がかかります。あなたは最適化しようとしている特定のクエリに役立つインデックスを入れてみることができます。また、生成されたSQLを見て、それがあなたが期待するほど良いことを確認することもできます。十分な単純なクエリなので、私はそれについてあまり心配する必要はありません)。またname == null || (x.name != null && (x.name.StartsWith(name)))

関連する問題