c# - linq 到实体 : linq query performance optimization

标签 c# mysql sql entity-framework linq-to-entities

我正在使用 EF 4.4.20627.0MySQL 5.6MySQL .net 连接器 版本 6.6.4

我有一个这样的方法,它生成的 sql 非常非常慢(需要超过 1 分钟)

    private List<TNews> GetPagedNews(int pagenum, int pagesize,
        AdvSearcherArgs advcArgs, string keyword)
    {
        var dataSrc = _dbRawDataContext.TNews.Where(x => x.Id>0);
        if (!string.IsNullOrWhiteSpace(advcArgs.PMAC))
        {
            dataSrc = dataSrc.Where(m => m.Pmac == advcArgs.PMAC);
        }
        if (!string.IsNullOrWhiteSpace(advcArgs.BegineDate))
        {
            var begin = Convertion.ToDate(advcArgs.BegineDate);
            var end = Convertion.ToDate(advcArgs.EndDate);

            dataSrc = dataSrc.Where(m => m.PmacDT >=begin && m.PmacDT<end);
        }
        dataSrc = dataSrc.OrderByDescending(n => n.PmacDT).Skip(pagenum * pagesize).
          Take(pagesize);

        var cnt = dataSrc.Count();
        SetPagerValues(pagenum, pagesize, cnt);

        return dataSrc.ToList();
    }

生成的sql是这样的:

SELECT
`Project1`.*
FROM 
(
   SELECT
   `Extent1`.*
   FROM `tnews` AS `Extent1`
   WHERE (`Extent1`.`Id` > 0) 
   AND ((`Extent1`.`PmacDT` >= '2013-01-01 00:00:00 ') AND          
        (`Extent1`.`PmacDT` < '2013-01-07 00:00:00 '))
) AS `Project1`
 ORDER BY 
`Project1`.`PmacDT` DESC LIMIT 0,20
/* Affected rows: 0  Found rows: 20  Warnings: 0  Duration for 1 query: 00:01:30 */

如果我将 order bylimit 子句移动到大括号中,此 sql 将非常快(成本低于 1秒):

SELECT
`Project1`.*
FROM 
(
   SELECT
   `Extent1`.*
   FROM `tnews` AS `Extent1`
   WHERE (`Extent1`.`Id` > 0) 
   AND ((`Extent1`.`PmacDT` >= '2013-01-01 00:00:00 ') AND          
        (`Extent1`.`PmacDT` < '2013-01-07 00:00:00 '))
   ORDER BY 
   `PmacDT` DESC LIMIT 0,20
) AS `Project1`
 /* Affected rows: 0  Found rows: 20  Warnings: 0  Duration for 1 query: 0.000 sec. */

ProjectXExtent1 是什么意思? 以及为什么 Entity Framework 不将 orderby * limit x,y 放在实际查询之外??

sql 很奇怪,肯定会使查询非常慢,我永远不会那样写 sql...那么如何让 EF 生成一个CORRECT sql??

有什么建议吗?

最佳答案

只是一个快速的猜测:Count() 和 ToList() 都执行查询。首先执行 ToList(),然后使用接收到的列表获取元素的数量。

像这样:

private List<TNews> GetPagedNews(int pagenum, int pagesize,
    AdvSearcherArgs advcArgs, string keyword)
{
    var dataSrc = _dbRawDataContext.TNews.Where(x => x.Id>0);
    if (!string.IsNullOrWhiteSpace(advcArgs.PMAC))
    {
        dataSrc = dataSrc.Where(m => m.Pmac == advcArgs.PMAC);
    }
    if (!string.IsNullOrWhiteSpace(advcArgs.BegineDate))
    {
        var begin = Convertion.ToDate(advcArgs.BegineDate);
        var end = Convertion.ToDate(advcArgs.EndDate);

        dataSrc = dataSrc.Where(m => m.PmacDT >=begin && m.PmacDT<end);
    }
    dataSrc = dataSrc.OrderByDescending(n => n.PmacDT).Skip(pagenum * pagesize).
      Take(pagesize);

    var myList = dataSrc.ToList(); //execute the query to an in-memory list

    var cnt = myList.Count(); //get the count from the already exeuted query
    SetPagerValues(pagenum, pagesize, cnt);

    return myList; //return the list
}

关于c# - linq 到实体 : linq query performance optimization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14191998/

相关文章:

c# - 如何在 C# 中创建 NVarchar(max) Sqlparameter?

c# - 如何为父对象属性设置默认绑定(bind)属性?

c# - 评论会减慢我网页的执行时间吗?

mysql - 服务器迁移,无法连接mysql

mysql - mysql的特殊条件查询

mysql - 使用 mdbtools 将 access db 转换为 sql

php - 对于基本操作,php 还是 sql 更快?

c# - 使用 DataTable 和 List<T> 加入和分组

c# - 带有 asp 内容的 Bootstrap 弹出窗口不起作用

c# - 在 Global.asax 中给定值的变量有时会返回错误的值