1

有一个 LINQ 查询:

int criteria = GetCriteria();
var teams = Team.GetTeams()
    .Where(team=> criteria == 0 || team.Criteria == criteria)
    .ToList();

从性能(或任何其他角度)将其转换为以下是否有意义?

var teams = Team.GetTeams();
if (criteria != 0)
{
    teams = teams.Where(team => team.Criteria == criteria);
}
teams = teams.ToList();

我有一套可靠的标准;我应该将它们分开并仅在必要时应用每个标准吗?或者只是将它们应用到一个 LINQ 查询中并留给 .NET 来优化查询?

请指教。欢迎任何想法!

PS 各位,我不用Linq2Sql,只用LINQ,那是纯C#代码

4

2 回答 2

5

首先,重要的是要了解 LINQ 实际上有多种变体,主要可以根据它们是使用表达式树还是编译代码来执行查询来划分。

Linq2Sql(以及将查询转换为另一种形式以执行查询的任何 Linq 提供程序)使用表达式树,以便可以分析查询并将其转换为另一种形式(通常是 SQL)。在这种情况下,提供者可以修改查询,潜在地执行某种程度的优化。我不知道目前有任何提供者这样做。

Linq to Objects 使用已编译的代码,并且将始终按照编写的方式执行查询。除了开发人员之外,没有机会优化查询。

其次,所有 Linq 查询都被延迟。这意味着在尝试获取结果之前不会实际执行查询。这样做的副作用是您可以分几个步骤构建查询,并且只会执行最终查询。问题中的第二个示例仍然只执行一个查询

如果您使用的是 Linq2Sql,那么这两个查询很可能具有大致相似的性能。但是,第一个示例扩展为处理许多标准可能会导致执行计划过于笼统,最终会降低性能。修剪后的查询不会冒这种风险,并且将为每个实际的条件排列生成一个执行计划。

如果您使用的是 Linq to Objects,那么第二个查询绝对是更可取的,因为第一个查询将为每个输入执行一次传递给 Where 的谓词,即使条件总是返回 true。

于 2012-04-23T05:30:39.977 回答
3

我认为第二个选项更好,因为它只检查标准值一次。而在第一个查询中,每行都检查标准。
但我也相信你不会从中获得任何显着的性能提升。它可以在具有大量记录的表上为您提供更好的结果(理论上)

于 2012-04-23T04:56:59.313 回答