如何检查任何连接和布尔检查之间的实体框架性能差异?

Posted

技术标签:

【中文标题】如何检查任何连接和布尔检查之间的实体框架性能差异?【英文标题】:How to check entity framework performance difference between a join with any and a boolean check? 【发布时间】:2020-01-23 07:28:04 【问题描述】:

我想知道是否有人可以告诉我运行这样的 EF 查询之间会有什么性能差异(如果有的话)

var users = _context.Users.Include(p => p.Photos)
   .Where(p => p.Photos.Any())
   .AsQueryable();

还有这个

var users = _context.Users.Include(p => p.Photos)
    .Where(p => p.HasPhoto == true) 
    .AsQueryable();

在“用户”上检查布尔值“HasPhoto”会更好,还是在 ICollection 上的 .Any() 在大型数据集上也能快速运行? 如何查看速度差异,使用什么工具?

【问题讨论】:

请记住,.Any 会自动增加获取Enumerator、调用MoveNext 和处理Enumerator 的开销。看看source code。 【参考方案1】:

为什么不试试呢!您可以使用计时器来测量展位的时间。尝试使用类似的东西

var watchOne = System.Diagnostics.Stopwatch.StartNew();
testOne();
watchOne.Stop();
var resOne = watchOne.ElapsedMilliseconds;

var watchTwo = System.Diagnostics.Stopwatch.StartNew();
testTwo();
watchTwo.Stop();
var resTwo= watchTwo.ElapsedMilliseconds;

public void testOne()
    var users = _context.Users.Include(p => p.Photos)
    .Where(p => p.Photos.Any())
    .AsQueryable();


public void testTwo()
    var users = _context.Users.Include(p => p.Photos)
    .Where(p => p.HasPhoto == true) 
    .AsQueryable();

【讨论】:

我没有大型数据集。如果数据集很大,不仅会产生显着差异吗? @user1186050 我不这么认为,我会使用Any() 方法,但这只是因为它更易于阅读且更直接。【参考方案2】:

整体考虑实体框架的性能考虑:

    加载和验证数据¹ 相对成本。 执行查询也有一个¹ 相对成本

¹[总成本的增加与查询返回的对象数量成正比]。

考虑到两者

var users = _context.Users.Include(p => p.Photos)
   .Where(p => p.Photos.Any())
   .AsQueryable();

var users = _context.Users.Include(p => p.Photos)
    .Where(p => p.HasPhoto == true) 
    .AsQueryable();

返回相同的结果,实际返回时间是毫秒。

不过,考虑到结果集比较大,考虑.Any()LINQ扩展方法

public static bool Any<TSource> (this System.Collections.Generic.IEnumerable<TSource> source)

并且此方法不返回集合的任何一个元素。相反,它确定集合是否包含任何元素(因此,减少了总执行时间)。

因此,最终,Any() 扩展方法的性能会更好。

【讨论】:

以上是关于如何检查任何连接和布尔检查之间的实体框架性能差异?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查实体框架中特定日期/工作日下一组值出现的次数

实体框架代码首先进行连接状态检查

检查“int”类型的“布尔”结果

如何检查任何多个“错误”布尔值是不是为真?

检查两个类列表之间的差异

是否可以使用 VImage 检查两个捕获的帧之间的差异?