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

Car*_*lis 14 .net sql-server entity-framework linq-to-sql compiled-query

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

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

- 编辑 -

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

我问这个的原因之一是因为有很多人似乎认为不再需要存储的程序因为不同的原因(即这篇文章).

Yak*_*ych 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代码并使其尽可能地与您的目标相匹配,从而提供在数据库级别获得最佳性能的可能性.

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


Dar*_*wis 5

"在任何情况下,存储过程都会表现得更好吗?"

给定在EF或存储过程中生成的可比较的参数化SQL,它们将执行相同的操作.

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

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

  • +1但不幸的是,我所工作的每项工作都需要使用存储过程,无论如何都要创建/更新开发人员的工作. (2认同)