2012-11-01 46 views
2

我对1 million数据在我的数据库(MySQLEF,如何提高查询性能

,并有一个填写AdvancedSearch功能是very slow(超过30秒),因为SQL的EntityFramework生成的不是很好, SQL:

SELECT 
`Project1`.* 
FROM 
(
SELECT 
`Extent1`.* 
FROM `tnews` AS `Extent1` 
WHERE `Extent1`.`Region` = 'Americas(2)' 
) AS `Project1` 
ORDER BY 
`Project1`.`PnetDT` DESC LIMIT 0,20 

C#功能:

private List<CNNews> AdvancedSearchAndPage(int pagenum, int pagesize, 
     AdvSearchArgs advArgs) 
    { 
     IQueryable<CNNews> result = _dbRawDataContext.CNNews. 
      OrderByDescending(n => n.PnetDT); 

     if (!string.IsNullOrWhiteSpace(advArgs.Feed)) 
     { 
      result = result.Where(news => news.Feed == advArgs.Feed); 
     } 

     if (!string.IsNullOrWhiteSpace(advArgs.PNET)) 
     { 
      result = result.Where(news=>news.PNET == advArgs.PNET); 
     } 

     if (!string.IsNullOrWhiteSpace(advArgs.ProdCode)) 
     { 
      result = (from news in result 
         where news.ProdCode == advArgs.ProdCode 
         select news); 
     } 

     if (!string.IsNullOrWhiteSpace(advArgs.Code)) 
     { 
      result = (from news in result 
         where news.Code == advArgs.Code 
         select news); 
     } 

     if (!string.IsNullOrWhiteSpace(advArgs.BegineDate)) 
     { 
      var begin = Convertion.ToDate(advArgs.BegineDate); 
      var end = Convertion.ToDate(advArgs.EndDate); 

      result = (from news in result 
         where news.PnetDT >= begin && news.PnetDT < end 
         select news); 
     } 

     if (!string.IsNullOrWhiteSpace(advArgs.Region)) 
     { 
      result = result.Where(x => x.Region == advArgs.RegionName); 
     } 

     var pagedList = result. 
      Skip(pagenum * pagesize). 
      Take(pagesize); 
     return pagedList.ToList(); 
    } 

如果SQL格式是这样,它会very fast

SELECT 
* 
FROM `tnews` AS `Extent1` 
WHERE `Extent1`.`Region` = 'Americas(2)' 
ORDER BY 
`PnetDT` DESC LIMIT 0,20 

回答

0

生成您的查询的LINQ看起来像这样:

IQueryable<CNNews> result = _dbRawDataContext.CNNews 
    .OrderByDescending(n => n.PnetDT) 
    .Where(x => x.Region == advArgs.RegionName) 
    .Skip(pagenum * pagesize) 
    .Take(pagesize); 

您告诉LINQ选择所有项目并订购它们。然后你告诉它需要一个子集。 SQL看起来和你指定的完全一样,我会说。

如果你重新排列你的代码有点使得Where()调用是OrderByDescending()呼叫我想你可能会得到更好的SQL之前:

IQueryable<CNNews> result = _dbRawDataContext.CNNews 
    .Where(x => x.Region == advArgs.RegionName) 
    .OrderByDescending(n => n.PnetDT) 
    .Skip(pagenum * pagesize) 
    .Take(pagesize); 

另外,我不知道,如果改变OrderByDescending()Skip()订单/ Take()会给出不同的结果。

(声明:我还没有测试过)

+0

你有没有看过这个问题? –

+0

是的。是什么让你觉得我没有? –

+0

关键是如何处理这些'如果' –