简体   繁体   English

EF,如何提高查询性能

[英]EF, how to increase query performance

i have about 1 million data in my database( MySQL ) 我的数据库中有大约1 million数据( 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: 还有一个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# function: 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();
    }

if the SQL format like this, it will very fast : 如果这样的SQL格式,它将very fast

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

You can execute your own SQL directly off the DbSet and get all the benefits of EF, see 您可以直接在DbSet上执行自己的SQL并获得EF的所有好处,请参见

http://msdn.microsoft.com/en-us/library/system.data.entity.dbset.sqlquery(v=vs.103).aspx 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? 是否可以在实体框架中运行本机sql?

The LINQ that generated your query looks something like this: 生成查询的LINQ看起来像这样:

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. 您告诉LINQ选择所有项目并订购它们。 Then you tell it to take a subset of that. 然后,您告诉它接受其中的一部分。 The SQL looks exactly like what you have specified, I would say. 我想说,SQL看起来和您指定的完全一样。

If you rearrange your code somewhat so that the Where() call is before the OrderByDescending() call I think you might get better SQL: 如果您对代码进行某种程度的重新排列,以使Where()调用位于OrderByDescending()调用之前, OrderByDescending()我认为您可能会获得更好的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. 另外,我不知道更改OrderByDescending()Skip() / Take()顺序是否会产生不同的结果。

(Disclaimer: I haven't tested it) (免责声明:我尚未测试)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM