LINQ to SQL何时编译查询可以提高性能?

12
我指的是一篇文章,它侧重于加速LINQ到SQL查询。其中提到的一个技术是“使用已编译的查询”,并解释了如何使用它。
我想看到编译查询的性能改进,因此我尝试了作者提供的相同示例。我使用Northwind Db作为数据上下文。我尝试了正常执行和编译查询执行,并在LINQ PAD上进行了检查。
首先,我尝试执行未使用CompileQuery的查询。它花费了2.065秒。
var oo =   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 100)
   select o;

oo.Dump ("Order items with unit price more than $100");

var oo1 = from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > 10)
   select o;

oo1.Dump ("Order items with unit price more than $10"); 

其次,使用CompileQuery的查询。花费了2.100秒。

var oo = CompiledQuery.Compile ((TypedDataContext dc, decimal unitPrice) =>    
   from o in Orders
   where o.OrderDetails.Any (p => p.UnitPrice > unitPrice)
   select o
);

oo (this, 100).Dump ("Order items with unit price more than $100");
oo (this, 10).Dump ("Order items with unit price more than $10");

重新多次执行它们的结果表明,这两种方法所需的时间几乎相同。
在这里,我们只看到每种方法执行了两个查询。我尝试对它们各自进行了10次查询,但它们都在大约7秒钟左右完成。
预编译查询是否真的可以提高性能?还是我的使用方式有误?
感谢您的时间和考虑。
编辑:阅读被接受的答案后,读者可能还想通过this article来了解如何编译查询以提高性能的详细说明。
1个回答

11
记住,LINQ查询中有两个主要部分可能特别昂贵:
  1. 将LINQ表达式编译成SQL语句。
  2. 运行SQL语句并检索结果。
在您的情况下,您有一个相对简单的查询,但是连接数据库很慢、数据集很大或表格没有以最优方式进行索引以运行此特定查询。或者可能是所有三者的组合。
因此,与生成查询的SQL所需的时间相比(可能为10-50毫秒),第二步所需的时间(约1000毫秒)太长,以至于几乎看不出差异。
如果符合以下所有条件,则可以看到明显的改进:
  1. 您的LINQ查询比较复杂,
  2. 您连接到数据库的速度较快,
  3. SQL查询本身在该数据库上快速运行,和
  4. 结果集足够小,可以相对快速地从数据库传输回来。
实际上,我曾经遇过需要耗费500毫秒以上来编译的查询,但实际运行只需要几毫秒。这通常是我专注于预编译查询的情况。
提前知道从预编译查询中可以期望什么样的性能收益的一个很好的方法是使用Stopwatch对象计时第二个查询实例,然后使用LINQPad的Analyze SQL功能直接运行生成的SQL。如果SQL查询返回很快,但是LINQ查询需要很长时间,则可以考虑预编译该查询。

这意味着在处理大型查询时,我们可以消除每次执行的编译时间,然后只考虑改进第二步(执行和检索结果)。 - Marshal
@Marshal:是的,那就是我们的想法。 - StriplingWarrior
非常感谢你,詹姆斯。这确实很有帮助。顺便说一下,我也喜欢阅读你的博客 ;) - Marshal
如果你说的是“大查询”,指的是具有许多复杂性(连接等)而不是具有许多结果的查询。 - Jon Hanna
1
值得注意的是,从.NET 4.5开始,LINQ查询会自动缓存,因此编译查询会有明显改善的机会更少。 - StriplingWarrior
1
@StriplingWarrier 这篇文章是关于Entity Framework的,但这个问题引用了Linq to SQL,据我所知它不包括任何自动查询缓存功能。 - bmode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接