Sql server LINQ实体摆脱sp_executesql

Sql server LINQ实体摆脱sp_executesql,sql-server,linq,sql-server-2008,linq-to-entities,sqlperformance,Sql Server,Linq,Sql Server 2008,Linq To Entities,Sqlperformance,我正在尝试使用优化我的数据库,我面临的问题是,我的SQL Profiler跟踪显示了使用sp_executesql执行的大量查询,而advisor无法处理这些查询。这些查询似乎来自我正在使用的LINQ到实体,所以我很好奇是否有任何方法可以让LINQ到实体直接调用语句。sp_executesql的使用是ADO.NET效果,而不是实体框架特有的。就我所知,没有办法指示它不要使用该存储过程。同意Adam的观点。在实体框架/ADO.net中使用sp_executesql是有意的。然后执行类似于参数化存储

我正在尝试使用优化我的数据库,我面临的问题是,我的SQL Profiler跟踪显示了使用
sp_executesql
执行的大量查询,而advisor无法处理这些查询。这些查询似乎来自我正在使用的LINQ到实体,所以我很好奇是否有任何方法可以让LINQ到实体直接调用语句。

sp_executesql的使用是ADO.NET效果,而不是实体框架特有的。就我所知,没有办法指示它不要使用该存储过程。

同意Adam的观点。在实体框架/ADO.net中使用sp_executesql是有意的。然后执行类似于参数化存储过程的查询,SQL优化器可以重用查询计划


<>如果你想调整你的数据库,你也应该考虑这些查询。我建议您备份数据库,使用replay跟踪模板(在SQL探查器中)捕获查询,恢复数据库,运行tuning advisor设置,将其工作负载加载到此跟踪,这只是探查器中如何显示RPC调用的一个工件。有两种主要类型的客户端请求:语言(类型0x01)和RPC(类型0x03),如。当调用是带有参数的SQL批处理时,RPC调用的类型为0x03,长度为0x0A,这是
sp\u executesql
的快捷方式


所以你看,真正发生的是,当一个客户机,任何一个客户机,提交一个包含参数的批处理时,它看起来就像调用了
sp\u executesql
。对于ODBC,OleDB,SqlClient,Sql原生客户端,正如我所说的,任何客户端都是如此。实体框架和实际调用sp_executesql的ADO.Net都不是这样(事实上,该过程甚至没有真正调用,尽管请求的执行就像调用它一样。很复杂…)。它是协议的产物,在您向请求添加
@参数时就会发生。

LINQ/.NET通过将SQL查询作为
sp\u executesql
调用发送到SQL server来运行SQL查询。但是,数据库引擎优化顾问无法解析SQL Server Profiler捕获的语句,因此优化会话的结果将很差

这就是我在将
sp_executesql
语句馈送到数据库引擎优化顾问之前如何“取消装箱”语句,以便它能够正确分析它们

  • SQL Server Profiler中运行(或打开现有)优化会话后,请使用文件>导出>提取SQL Server事件>提取Transact-SQL事件。。。保存包含所有SQL语句的.SQL文件
  • 打开.SQL文件(例如,Notepad++6-)并运行以下查找和替换正则表达式,将所有
    sp_executesql
    语句取消装箱到普通TSQL。查找:
    ^EXEC[\s]+SP_EXECUTESQL[\s]+[N]*'(('''.[^'])*,[\s]*[N]*'(('.'.[^'])*)[\s]*,[\s]*([^\N]+)$
    替换:
    开始声明\3\N选择\5\N\1\nEND
  • 接下来,使用我们刚刚在数据库引擎优化顾问中构建的“unbox”.SQL字段,找出需要添加的索引
    调音愉快!请注意,我选择了Notepad++6(或更高版本),因为它有一个非常好的正则表达式实现,其他文本编辑器可能无法运行上面的表达式。

    非常感谢,我将尝试这种方法!谢谢你的解释-它澄清了很多事情。。现在我明白怎么回事了!你为什么不在最高层?这个简单的查找和替换确实奏效了。除了EF对每个过程调用使用相同的变量名之外。但这真的很有帮助。谢谢你,伙计!更新到“查找”表达式:^EXEC[\s]+SP|u EXECUTESQL[\s]+[N]*((“”””)[\s]*,[\s]*[N]*”((““”””)(“““””””,[\s]*)”[\s]*([\s]*,[\s]*([^\N]+)$