Reputation: 2332
i have about 1 million
data in my database(MySQL
)
and there's a advancedSearch function which is very slow
(more than 30 sec), because the SQL EntityFramework generated is not very good, 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# function:
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();
}
if the SQL format like this, it will very fast
:
SELECT
*
FROM `tnews` AS `Extent1`
WHERE `Extent1`.`Region` = 'Americas(2)'
ORDER BY
`PnetDT` DESC LIMIT 0,20
Upvotes: 2
Views: 260
Reputation: 1986
The LINQ that generated your query looks something like this:
IQueryable<CNNews> result = _dbRawDataContext.CNNews
.OrderByDescending(n => n.PnetDT)
.Where(x => x.Region == advArgs.RegionName)
.Skip(pagenum * pagesize)
.Take(pagesize);
You tell LINQ to select all items and order them. Then you tell it to take a subset of that. The SQL looks exactly like what you have specified, I would say.
If you rearrange your code somewhat so that the Where()
call is before the OrderByDescending()
call I think you might get better SQL:
IQueryable<CNNews> result = _dbRawDataContext.CNNews
.Where(x => x.Region == advArgs.RegionName)
.OrderByDescending(n => n.PnetDT)
.Skip(pagenum * pagesize)
.Take(pagesize);
Also, I don't know if changing order of OrderByDescending()
and Skip()
/Take()
would give different results.
(Disclaimer: I haven't tested it)
Upvotes: 0
Reputation: 6136
You can execute your own SQL directly off the DbSet and get all the benefits of EF, see
http://msdn.microsoft.com/en-us/library/system.data.entity.dbset.sqlquery(v=vs.103).aspx
Also other ways, see these answers for more details
Is it possible to run native sql with entity framework?
Upvotes: 1