使用编译查询时,我们是否还需要存储过程?

时间:2010-09-27 08:19:16

标签: .net sql-server linq-to-sql entity-framework compiled-query

在实体框架(或linq-to-sql)中与SQL Server结合使用编译查询时,使用存储过程实际上是否仍有任何性能优势?

编译的查询将作为参数化查询进行缓存,因此性能应该接近存储过程。是否存在存储过程表现更好的情况?

- 编辑 -

为了回应下面的Yakimych的回答,我并不是要暗示编译的查询与存储过程相同。如果你在应用程序端完成所有可能的优化(在这种情况下是编译查询),我试图找出是否仍然需要sprocs。所以我想我正在寻找为什么存储过程比应用程序端优化和参数化查询的组合更好的原因(这是有效的编译查询)。

我问这个问题的原因之一是因为有很多人似乎认为不再需要存储的程序因为不同的原因(即this post)。

3 个答案:

答案 0 :(得分:9)

首先,编译EF查询与使用存储过程可以实现的性能优势无关。

根据http://msdn.microsoft.com/en-us/library/cc853327.aspx - 对概念模型执行查询时会发生以下操作:

  
      
  • 加载元数据
  •   
  • 打开数据库连接
  •   
  • 生成视图
  •   
  • 准备查询
  •   
  • 执行查询
  •   
  • 加载和验证类型
  •   
  • 跟踪
  •   
  • 实现对象
  •   

关于Preparing the query的解释:

  

包括组成查询命令的成本,基于模型和映射元数据生成命令树,以及定义返回数据的形状。由于实体SQL查询命令被缓存,因此稍后执行同一查询所需的时间更少。您还可以使用已编译的LINQ查询在以后的执行中降低此成本。

因此,如果您编译查询并在以后重新使用它,那么在每次后续查询执行期间,您将在应用程序中节省此操作的时间。但是,您不做的是不影响针对数据库执行的生成的SQL代码。 在编译查询时,您在应用程序级别获得的性能优势。

另一方面,如果您对生成的SQL代码不满意并希望在数据库级别优化性能,通常会使用存储过程。

编辑以回复您的评论和修改。

在我看来,您认为编译EF查询会以某种方式更改将针对数据库运行的生成的SQL代码(您提到编译的查询会导致参数化的SQL查询吗?)。事实并非如此。无论您是直接运行查询还是使用compiledQuery.Invoke都将对DB 运行相同的SQL代码。此外,您无法完全控制它,而是依靠ORM以最佳方式生成它。在某些情况下,它不是最佳的,这就是SP的用武之地。

总结一下:

  • 编译查询纯粹是一个 应用程序端优化。它 节省了编译查询的时间 在代码中重复使用。
  • 存储过程可用于调整SQL代码并使其尽可能与您的目标相匹配,从而提供在数据库级别获得最佳性能的可能性。

绝不是一种技术可以替代另一种技术。

答案 1 :(得分:5)

  

“存储过程是否会出现明显改善的情况?”

鉴于在EF或存储过程中生成的可比较的参数化SQL,它们将表现相同。

但是,DBA始终有机会根据他们对数据库架构及其使用模式的体验进一步优化查询。存储过程允许它们在使用它的应用程序中轻松地完成此操作,而ORM则不能。

我们有一个非常复杂的SQL Server数据库,它有许多外部系统通过触发器复制数据。我们使用EF的问题是,在使用任何ORM而不是DBA时,对DB的责任将成为应用程序开发人员的责任。

答案 2 :(得分:3)

来自知名专家的一些罐头答案:Paul Nielsen Why use Stored Procedures?

Adam Machanic:No, stored procedures are NOT bad