【问题标题】:LINQ-to-Entities get rid of sp_executesqlLINQ-to-Entities 摆脱 sp_executesql
【发布时间】:2010-06-27 05:04:04
【问题描述】:

我现在正在尝试使用 Database Engine Tuning Advisor 优化我的数据库,而我面临的问题是我的 SQL Profiler 跟踪显示使用 sp_executesql 执行的大量查询 - 并且顾问无法处理这些查询。这些查询似乎来自我正在使用的 LINQ-to-Entities,所以只是好奇是否有任何方法可以让 LINQ-to-Entities 直接调用语句。

【问题讨论】:

    标签: sql-server linq sql-server-2008 linq-to-entities sqlperformance


    【解决方案1】:

    LINQ/.NET 通过将 SQL 查询作为 sp_executesql 调用发送到 SQL 服务器来运行它们。但是,Database Engine Tuning Advisor 无法通过 SQL Server Profiler 解析捕获的语句,因此调整会话的结果会很差。

    这就是我在将sp_executesql 语句提供给数据库引擎优化顾问之前“拆箱”它们的方式,以便它可以正确分析它们。

    1. SQL Server Profiler 中运行(或打开现有)优化会话后,使用 File>Export>Extract SQL Server Events>Extract Transact-SQL Events... 保存一个包含所有 SQL 语句的 .SQL 文件。
    2. 打开 .SQL 文件(例如 Notepad++ 6 - http://notepad-plus-plus.org/)并运行以下查找和替换正则表达式以将所有 sp_executesql 语句拆箱为纯 TSQL。查找:^EXEC[\s]+SP_EXECUTESQL[\s]+[N]*'((''|[^'])*)'[\s]*,[\s]*[N]*'((''|[^'])*)'[\s]*,[\s]*([^\n]+)$ 替换:BEGIN\nDECLARE \3\nSELECT \5\n\1\nEND
    3. 接下来,使用我们刚刚在 Database Engine Tuning Advisor 中构建的“未装箱”.SQL 文件找出您需要添加的索引。

    调音愉快!请注意,我选择了 Notepad++ 6(或更高版本),因为它有一个非常好的正则表达式实现,其他文本编辑器可能无法运行上面的表达式。

    【讨论】:

    • 你为什么不在榜首?这个简单的查找和替换确实起到了作用。除了 EF 对每个过程调用使用相同的变量名。但是这个^真的很有帮助。谢谢老哥!
    • 更新到“查找”表达式:^EXEC[\s]+SP_EXECUTESQL[\s]+[N]*'((''''|''|[^']*)* )'[\s]*,[\s]*[N]*'((''''|''|[^']*)*)'[\s]*,[\s]*([ ^\n]+)$
    【解决方案2】:

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

    如果您希望调整您的数据库,您也应该考虑这些查询。我建议你备份你的数据库,使用重放跟踪模板(在你的 SQL 分析器中)捕获查询,恢复你的数据库,运行你的调整顾问设置它的工作负载到这个跟踪

    【讨论】:

    • 非常感谢,要试试这个方法!
    【解决方案3】:

    这只是 RPC 调用如何在分析器中显示的工件。有两种主要类型的客户端请求:语言(类型 0x01)和 RPC(类型 0x03),如 Free TDS protocol documentation 所述。当调用是带参数的 SQL 批处理时,RPC 调用的类型为 0x03,长度为 0x0A,这是sp_executesql 的快捷方式。

    所以你看,真正发生的是当一个客户端,任何客户端,提交一个包含参数的批处理,它看起来好像sp_executesql 正在被调用。 ODBC、OleDB、SqlClient、Sql Native Client 都是如此,正如我所说的,any 客户端。实际调用 sp_executesql 的实体框架和 ADO.Net 也不是(事实上,该过程甚至没有真正被调用,尽管请求的执行就像它被调用一样。很复杂......)。它是协议的产物,只要您在请求中添加 @parameter,就会发生这种情况。

    【讨论】:

    • 感谢您的解释 - 它澄清了很多事情......现在我明白发生了什么!
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      相关资源
      最近更新 更多