我的数据库中有1 million
个数据MySQL
并且有一个高级搜索功能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 :(得分:1)
您可以直接在DbSet上执行自己的SQL并获得EF的所有好处,请参阅
http://msdn.microsoft.com/en-us/library/system.data.entity.dbset.sqlquery(v=vs.103).aspx
其他方式,请参阅这些答案以获取更多详细信息
答案 1 :(得分: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()
的顺序是否会产生不同的结果。
(免责声明:我没有测试过它)