Linq to SQL慢速查询

时间:2016-06-22 20:18:15

标签: c# sql-server linq

我的ASP.Net应用程序具有以下Linq to 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,它显示此查询正在使用大量资源。

Redgate还显示我正在运行以下查询:

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]))
  3. 产品中有90,000条记录。这个类别,我试图获得不同的高度列表有50,000个产品记录

    提前谢谢你,

    尼克

2 个答案:

答案 0 :(得分:1)

首先,你发布的sql查询和linq查询根本不匹配。它不是LINQ查询而是底层SQL查询本身执行速度慢。确保JOIN ON子句和WHERE子句以及ORDER BY子句中涉及的所有列都已正确编入索引,以便获得更好的执行计划;否则,您最终会获得FULL Table ScanFile Sort,并且查询将被视为执行缓慢。

答案 1 :(得分:0)

连接乘以查询返回的Product个数。要撤消该操作,请在结尾处应用Distinct。如果您立即返回唯一的Product,它肯定会减少数据库资源:

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);

这会将join更改为where子句。它为db引擎节省了重复数据删除的麻烦。

如果仍然表现不佳,你应该尝试在内存中进行转换和排序,即从数据库接收原始结果后。

至于伯爵。我不知道它来自哪里。此类查询通常由分页库(如PagedList)生成,但我在您的代码中看不到它的痕迹。

旁注:你可以退货......

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

...而不是自己创建列表。