这两个 LINQ to SQL 查询之间的性能是否有任何差异?



我最近一直在研究我的 Web 应用程序性能,发现了一些 LINQ 查询,我不确定更改它们是否会提高性能。

基本上当前的代码如下所示:

var result = _carsRepository.GetAll()
.Where(x => x.Name == input.Name)
.FirstOrDefault();
if (result != null)
{
throw new Exception("test");
}

我正在考虑将其更改为:

var result = _carsRepository.GetAll()
.Where(x => x.Name == input.Name)
.Any();
if (result)
{
throw new Exception("test");
}

根据我的理解,第一个查询将返回一个实际的实体,我不需要它,因为我只想知道数据库中是否已存在同名的记录。第二个查询只返回一个布尔值。

我将不胜感激任何评论。

编辑:我可以在EF db上下文上运行查询,所以请忽略它。 当前存储库是一个通用的 Abp.Domian.Repository。 GetAll(( 返回 IQueryable

我不确定GetAll()做什么。如果它将所有项目从您的数据库移动到您的本地内存,那么我不会打扰:尝试改进该语句。如果您只需要第一个项目,为什么要获取所有项目。

如果GetAll()返回一个IQueryable<...>,则略有不同:

FirstOrDefault()将更改查询中的表达式,以便 SQL 语句Select top 1 ... from

更改表达式后,它将要求IQqueryableProvider执行Expression,SQL语句的完整结果将b传输到本地内存,在这种情况下将是一个项目。

Any()几乎会做同样的事情,除了SQL将是:Select top 1 1 from ...

很容易看出,Select top 1 1最多会传输一个整数,而Select top 1将传输所有选定的列。

因此,如果您只想检查是否有任何元素,Any()FirstOrDefault更有效

我们无法告诉您,因为我们既不知道您的存储库类是做什么的,也不知道您的数据库驱动程序如何处理到 SQL 的转换。

测试两者,对它们进行基准测试,查看 SQL,并检查您的数据库分析工具是否可能错过索引或其他优化机会。

仅从Linq就无法分辨。

可能会有细微的差异,因为

.FirstOrDefault()- 读取所有列

.Any()- 只需检查是否有条目

差异将主要基于数据大小和SQL结构,索引和所有。建议通过测试对它们进行基准测试

No.您可能不会获得任何性能差异。因为

1(Any((将在找到匹配项后立即返回。

2(FirstOrDefault(( 迭代(可能(在找到满足条件的元素时停止。

LINQ to objects:Enumerable.Any 和Enumerable.FirstOrDefault应执行相同的操作,因为它们的代码几乎相同:

优先或默认:

foreach (TSource source1 in source)
{
if (predicate(source1))
return source1;
}
return default (TSource);

任何:

foreach (TSource source1 in source)
{
if (predicate(source1))
return true
}
return false;

现在。看起来您正在从内存中的数据库中获取所有记录,然后应用 where 子句。

尽量避免在内存中一次加载数据。然后它会给你性能差异

如前所述,目前还不清楚您的存储库是做什么的。但是,如果您遵循存储库模式,则应考虑将 Any 添加为存储库中的方法。

public virtual bool Any(Expression<Func<T, bool>> predicate)
{
return _context.Set<T>().Any(predicate);
}

这将确保您的 Any 在数据库上执行,因为此方法将 Any 作为 IQueryable 执行。

如果您没有在存储库中使用泛型,则将 T 替换为目标类。

最新更新