【问题标题】:Does SET NOCOUNT ON really make that much of a performance differenceSET NOCOUNT ON 真的会产生这么大的性能差异吗
【发布时间】:2010-12-27 06:56:13
【问题描述】:
在这个article 中,作者建议存在与SET NOCOUNT ON 相关的物质开销,并且“通过从网络中移除这些额外开销,它可以大大提高您的数据库和应用程序的整体性能”
作者引用了默认存储过程模板从 2000 年到 2005 年的变化,并暗示“微软甚至意识到了这个问题”,这促使了这个模板的变化。
是否有人有确凿的证据支持或反驳通过将 NOCOUNT 设置为 ON 所声称的性能提升。
【问题讨论】:
标签:
sql-server-2005
performance
【解决方案1】:
在某些情况下 SET NOCOUNT ON 是强制性的。在通过 SqlClient 的 BeginExecuteXXX 方法利用线程池设计基于异步处理的高性能中间层时,行计数存在非常严重的问题。当服务器返回 first 响应数据包时,BeginExecute 方法就完成了。但是当调用 EndExecuteXXX 时,当调用完成时,这会在非查询请求上完成。每个 rowcount 响应都是一个响应。在处理甚至中等复杂的过程时,第一行计数可能会在 5-10 毫秒内返回,而调用在 300-500 毫秒内完成。它不是在 500 毫秒后回调提交的异步请求,而是在 5 毫秒后回调,然后在 EndExecuteXXX 中回调阻塞 495 毫秒。结果是异步调用过早完成并在 EndExecuteNonQuery 调用中阻塞线程池中的线程。这会导致线程池饥饿。我已经看到高性能系统通过在特定场景中添加 SET NOCOUNT ON 将吞吐量从每秒数百次调用提高到每秒数千次调用。
鉴于对于大规模/高吞吐量中间层处理异步调用是唯一的方法,NOCOUNT 几乎是强制性要求。
【解决方案3】:
我同意使用 NOCOUNT 是个好主意。
将它添加到每个 SPROC 或动态 SQL 语句中执行的所有代码中是一个糟糕的主意。
尤其是当您谈论高性能时。 TSQL NOCOUNT 应根据数据访问层中的代码的需要进行设置。就像事务和锁定级别一样。
在每次执行的 SQL 中每次都设置这些东西并不能通过在连接应用程序的代码中设置它们来获得巨大的性能提升。
通过编写更好的代码而不是通过将 SET NOCOUNT 语句添加到所有 SQL 来获得更好的性能。