2013-03-06 74 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};