2016-06-22 28 views
0

私のASP.Netアプリケーションには、Productテーブルから高さ値の明確なリストを取得するために、次のLinq to SQL関数があります。LinqからSQLへのスロークエリ

public static List<string> getHeightList(string catID) 
     { 
      using (CategoriesClassesDataContext db = new CategoriesClassesDataContext()) 
      {  
       var heightTable = (from p in db.Products 
            join cp in db.CatProducts on p.ProductID equals cp.ProductID 
            where p.Enabled == true && (p.CaseOnly == null || p.CaseOnly == false) && cp.CatID == catID 
            select new { Height = p.Height, sort = Convert.ToDecimal(p.Height.Replace("\"", "")) }).Distinct().OrderBy(s => s.sort); 

       List<string> heightList = new List<string>(); 

       foreach (var s in heightTable) 
       { 
        heightList.Add(s.Height.ToString()); 
       } 

       return heightList; 
      } 
     } 

私はこのクエリが多くのリソースを使用していることを示すRedgate SQL Monitorを実行しました。

レッドゲートはまた、私は次のクエリを実行していることを示している:

select count(distinct [height]) from product p 
join catproduct cp on p.productid = cp.productid 
join cat c on cp.catid = c.catid 
where p.enabled=1 and p.displayfilter = 1 and c.catid = 'C2-14' 

私の質問は以下のとおりです。

  1. それが少ないリソースを使用するように、機能を変更する提案?
  2. また、linq to sqlは私の関数から上記のクエリをどのように生成しますか? (私はコード内の任意の場所にselect count(distinct [height])を書きませんでした)

製品には9万レコードあります。私は高さの明確なリストを取得しようとしています。このカテゴリには、50,000製品のレコードを持っている

、事前にありがとう

ニック

+1

SQLをSQL Server Management Studioにコピーし、実行計画を取得します。あなたの質問に実行計画を掲載してください。 cat.catidはインデックスに登録されているのですか? –

+2

投稿されたSQLクエリとlinqクエリがまったく一致しません – Rahul

+0

Management Studioでそのクエリを試しましたか?期待される実行計画機能で調査します。これにより、テーブルにインデックスがない場合のヒントが得られます –

答えて

0

この結合によって、クエリから返されるProductの数が乗算されます。元に戻すには、最後にDistinctを適用します。あなたはすぐにユニークProduct sを返します場合、それは確かにDBリソースを削減します:

var heightTable = (from p in db.Products 
        where p.CatProducts.Any(cp => cp.CatID == catID) 
         && p.Enabled && (p.CaseOnly == null || !p.CaseOnly) 
        select new 
          { 
           Height = p.Height, 
           sort = Convert.ToDecimal(p.Height.Replace("\"", "")) 
          }).OrderBy(s => s.sort); 

これはwhere句にjoinを変更します。 dbエンジンに結果を重複排除する手間を省きます。

それでもパフォーマンスが悪い場合は、データベースから生の結果を受け取った後に、変換と並べ替えをメモリ内で行うようにしてください。

カウントについては、私はそれがどこから来るのか分からない。このようなクエリは、PagedListなどのページングライブラリによって生成されるのが一般的ですが、コード内にそのトレースはありません。

サイドノート:あなたの代わりに、リストを自分で作成するの... ...

heightList.Select(x => x.Height.ToString()).ToList() 

を返すことができます。

+0

Gertに助けていただきありがとうございますが、同じ高さの複数の製品が存在する可能性があるため、依然として区別が必要です。 – LockDev

+0

OK、少なくともこのコードは、dbエンジンに小さい値のセットを与えます。 –

1

すべての投稿のSQLクエリとLINQクエリがで一致していないのファーストすべて。 LINQクエリではなく、基礎となるSQLクエリ自体が遅いです。 JOIN ON句とWHERE句とORDER BY句に含まれるすべての列は、より良い実行計画を得るために適切に索引付けされていることを確認してください。そうでなければ、FULL Table ScanFile Sortが得られ、クエリは遅く実行されるとみなされます。

+0

私はSQLクエリとlinqクエリが一致しないことを認識しています。私はちょうど私のコードのどこにでもSQLクエリが表示されないので、SQLにlinqが余分なクエリを生成するかどうかは不思議です。 – LockDev