ado linq 查询奇慢无比

cpp_1 2020-11-28 11:26:58
数据库用的是MS-SQL单表,数据量大概在1千条左右

界面用提winform

用的是ADO实体,把数据库对像映射出来

现在就只做了一句LINQ,这个form现在打开奇慢无比,还一下子多出来一堆的事件。

就这个COUNT需要2-3分钟



不知道哪里出问题了。
...全文
5473 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2020-11-30
  • 打赏
  • 举报
回复
用法问题,最后 你在第一个 form a in 表 .toList()时,就代表把全部数据加载下来了。 这个应该放到最后、 (from a in 表.............where ........).ToList();
xiaoxiangqing 2020-11-30
  • 打赏
  • 举报
回复
1千条数据很少了,不应该这么慢
SayoKun 2020-11-30
  • 打赏
  • 举报
回复
引用 10 楼 cpp_1 的回复:
谢谢大家 但在问一句,这个1千条数据,就是全部加载到内容里面,也会查询这么慢嘛(差不多,要查3分钟)
你这1千条数据是先从数据库查询出来,传给你查询的机器,然后你查询的机器在得到这1千条数据后又按照你的条件去进行了where,select。最终才返回的结果~这其中数据库返回数据的时间和你本机遍历条件的时间你可以自己测一下,然后循环遍历1千次数据结果耗时多少你也可以测一下。3分钟是有点久~但是你这个语句最后执行的过程肯定都是可以单独分开来测试的(可以使用StopWatch来检测每一步的具体耗时),自己测一测就知道具体耗时在哪里了。
cpp_1 2020-11-30
  • 打赏
  • 举报
回复
谢谢大家 但在问一句,这个1千条数据,就是全部加载到内容里面,也会查询这么慢嘛(差不多,要查3分钟)
SayoKun 2020-11-30
  • 打赏
  • 举报
回复
上面很多大佬都解释了为什么这么慢的原因,以及解决办法。 这里就简单说一下ToList()放前面和放后面产生Sql的区别。 当ToList()在前面的时候Sql会把所有结果都先查询出来(select * from table)然后本机再去一条一条的where,这样效率就会低下。 当ToList()在后面的时候Sql就相当于select * from table where name ='xxx'然后返回到本机,这样本机只用直接返回结果就行了,所以会快很多。 在用Linq的时候要注意取结果的位置,位置不同最后的效果也不同。
  • 打赏
  • 举报
回复
除此之外,我觉得的值得怀疑一下你的 AsNoTracking() 这个的东西的设计问题。你可以使用直接的 ADO.NET 框架查询一下数据,也费不了什么事儿。就好像用100块钱到大医院能看好的小感冒,先不要到花你5000块钱的诊所去看。
  • 打赏
  • 举报
回复
哦,可能稍微改一下上面的变量命名
var f = (..........).FirstOrDefault();
免得认为此 query 就是之前的 query。
  • 打赏
  • 举报
回复
ToList 操作不要使用在 where 判断之前;同时如果又要 .Count() 又要遍历的话,不应该针对一个查询(表达式)对象直接调用这两个功能,而应该针对一个 ToList 结果进行这两个操作。

例如:
var query = from x in xxxTablProvider where x......... select new {.....};
var result = query.ToList();
if(result.Count >0)
.......
foreach(var x in result)
{
.......
}


查询表达式对象 query,它是“延迟执行”的,你每一次调用 Count()、遍历,以及其它方法,实际上都重新执行了一遍数据库查询和加载过程。所以应该一次性地把查询结果复制到一个你存 List 数据结构中,再执行 Count() 和遍历。

同样地,如果你过早执行 ToList 操作,那么你把表中所有数据整个加载到客户端内存并且反序列化,之后才在内存中执行 Linq to object 的 where 查询。而并不是使用 linq to 数据库provider 将 where 查询条件传给数据库端去查询。这显然在表中数据稍微多一些时是不行的。

最后,假设业务逻辑仅仅是判断“是否表中有符合 where 条件的设备”,而并不需要全都在客户端显示出具体明细,那么写
var query = (..........).FirstOrDefault();
就足够了,顶多让数据库返回一条(第一条)匹配记录就够了。将数据反序列化客户端内存,是最浪费时间的一个步骤。
八爻老骥 2020-11-29
  • 打赏
  • 举报
回复
引用 4 楼 cpp_1 的回复:
我后来改成 lambda表达式

var query = db.pc_info.Where(x => x.mac_address == tempmac);

if (query.Count() !=0)
{....}

这样就正常速度了

当时我也就随手写了一句查询,想着就单条件,也没多想。

哪知道这个数据库里面只有1千条,就变成这样了


如二楼所说,一个是加载所有数据到内存中再迭代过滤,一个是直接数据库里条件查询,速度肯定不一样。
cpp_1 2020-11-29
  • 打赏
  • 举报
回复
cpp_1 2020-11-29
  • 打赏
  • 举报
回复
我后来改成 lambda表达式 var query = db.pc_info.Where(x => x.mac_address == tempmac); if (query.Count() !=0) {....} 这样就正常速度了 当时我也就随手写了一句查询,想着就单条件,也没多想。 哪知道这个数据库里面只有1千条,就变成这样了

8,494

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧