首先,编译 EF 查询与使用存储过程可以实现的性能优势无关。
根据http://msdn.microsoft.com/en-us/library/cc853327.aspx - 当针对概念模型执行查询时会发生以下操作:
- 加载元数据
- 打开数据库连接
- 生成视图
- 准备查询
- 执行查询
- 加载和验证类型
- 追踪
- 物化对象
以及有关的解释Preparing the query
:
包括编写查询命令、基于模型和映射元数据生成命令树以及定义返回数据的形状的成本。因为 Entity SQL 查询命令被缓存,相同查询的以后执行花费更少的时间。您还可以使用已编译的 LINQ 查询来降低以后执行的成本。
因此,如果您编译查询并在以后重新使用它,那么您会在每次后续查询执行期间节省应用程序中此操作的时间。但是,您不做的是不影响针对数据库执行的生成的 SQL 代码。编译查询时获得的性能优势是在应用程序级别。
另一方面,您通常会使用存储过程,以防您对生成的 SQL 代码不满意并希望在数据库级别优化性能。
编辑以回应您的评论和编辑。
在我看来,您的印象是编译 EF 查询会以某种方式更改将针对数据库运行的生成的 SQL 代码(您提到编译的查询会导致参数化的 SQL 查询?)。事实并非如此。无论您是直接运行查询还是使用查询compiledQuery.Invoke
,都将对数据库运行相同的 SQL 代码。此外,您无法完全控制它,而是依靠 ORM 以最佳方式生成它。在某些情况下,它不是最优的,这就是 SP 的用武之地。
所以总结一下:
- 编译查询纯粹是应用程序端的优化。它节省了编译在代码中重复使用的查询的时间。
- 存储过程可用于调整您的 SQL 代码并使其尽可能接近您的目标,从而提供在数据库级别获得最佳性能的可能性。
绝不是一种技术可以替代另一种技术。