2013-03-06 119 views
3

我們正在使用實體框架來獲取一些數據。 LINQ查詢使用多個連接,如下面的代碼所示。我被要求將其更改爲SQL存儲過程,因爲它更快。我如何優化這個LINQ代碼,爲什麼它很慢?性能的LINQ VS SQL存儲過程

var brands = (from b in entity.tblBrands 
          join m in entity.tblMaterials on b.BrandID equals m.BrandID 
          join bm in entity.tblBranchMaterials on m.MaterialID equals bm.MaterialID 
          join br in entity.tblBranches on bm.BranchID equals br.BranchID 
          where br.BranchID == branch.branchId 
          select new Brand { brandId=b.BrandID, brandName=b.BrandName, SAPBrandId=b.SAPBrandID}).Distinct(); 
      return brands.ToList(); 
+3

誰告訴你存儲過程更快就是完全錯誤。 EF使用實際存在特殊存儲過程的參數化查詢。 – Aron 2013-03-06 07:53:15

回答

5

我懷疑主要的性能問題是由於我的一個主要抱怨。濫用關鍵字加入。

由於的使用JOIN,你得到的結果太多。所以你使用了DISTINCT。更糟糕的是,你對外部結果集是這樣做的,該SQL服務器沒有索引。

var brands = from b in context.Brands 
where 
    (from m in context.Materials 
     where b.BrandID == m.BrandID 
     where (from bm in context.BranchMaterials 
       where (from br in context.Branches 
         where bm.BranchID == br.BranchID 
         where br.BranchID == branch.branchId 
         select br).Any() 
       where m.MaterialID == bm.MaterialID select bm).Any() 
     select m).Any() 
    ).Any() 
select b; 

應該更高性能。然而,這仍然是錯誤的。由於使用的ORM時,我們應該考慮團體和連接。假設你的模型有任何意義,我會做以下事情。

var brands = from b in context.Brands 
      where (from m in b.Materials 
        //Assuming that BranchMaterials is just a Many-Many mapping table 
        from br in m.Branches 
        where br.BranchID == branch.branchId).Any()  
       select new Brand { brandId=b.BrandID, brandName=b.BrandName, SAPBrandId=b.SAPBrandID};