设置NOCOUNT ON使用情况

gbn*_*gbn 320 sql t-sql sql-server concurrency ado.net

灵感来自这个问题,对于SET NOCOUNT有不同的看法......

我们应该为SQL Server使用SET NOCOUNT ON吗?如果没有,为什么不呢?

它的作用编辑6,2011年7月22日

它会在任何DML之后抑制"​​xx行受影响"消息.这是一个结果集,当发送时,客户端必须处理它.它很小,但可以测量(见下面的答案)

对于触发器等,客户端将收到多个"受影响的xx行",这会导致某些ORM,MS Access,JPA等出现各种错误(参见下面的编辑)

背景:

一般接受的最佳实践(我想直到这个问题)是SET NOCOUNT ON在SQL Server中的触发器和存储过程中使用.我们在任何地方都使用它,快速谷歌显示大量的SQL Server MVP也同意.

MSDN表示这可能会破坏.net SQLDataAdapter.

现在,这对我来说意味着SQLDataAdapter仅限于完全简单的CRUD处理,因为它希望"n行受影响"消息匹配.所以,我不能用:

  • 如果EXISTS避免重复(没有行影响消息)注意:请谨慎使用
  • 什么不存在(预期行数较少)
  • 过滤掉琐碎的更新(例如,没有数据实际更改)
  • 之前进行任何表访问(例如记录)
  • 隐藏复杂性或denormlisation
  • 等等

在问题marc_s(谁知道他的SQL的东西)说不要使用它.这与我的想法不同(我认为自己在SQL方面也有一定的能力).

有可能我错过了一些东西(随意指出明显的东西),但你们有什么想法呢?

注意:我看到这个错误已经好几年了,因为我现在不使用SQLDataAdapter.

在评论和问题后编辑:

编辑:更多想法......

我们有多个客户端:一个可以使用C#SQLDataAdaptor,另一个可以使用Java中的nHibernate.这些可能会以不同的方式受到影响SET NOCOUNT ON.

如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的而工作则是不好的形式(反模式).

编辑2:触发器打破nHibernate问题,SET NOCOUNT ON无法设置

(不,它不是一个重复的这个)

编辑3:更多信息,感谢我的MVP同事

编辑2011年5月13日

如果没有指定,还会破解Linq 2 SQL吗?

编辑2011年6月14日

使用表变量打破JPA,存储过程:JPA 2.0是否支持SQL Server表变量?

编辑6:2011年8月15日

SSMS"编辑行"数据网格需要SET NOCOUNT ON:使用GROUP BY更新触发器

编辑2013年3月7日7:07

来自@RemusRusanu的更深入的细节:
SET NOCOUNT ON是否真的产生了很大的性能差异

Sed*_*glu 230

好了,我已经完成了我的研究,这是交易:

在TDS协议中,每个查询SET NOCOUNT ON只保存9个字节,而文本"SET NOCOUNT ON"本身是高达14个字节.我曾经认为这123 row(s) affected是从一个单独的网络数据包中以纯文本形式从服务器返回的,但事实并非如此.事实上,它是一个称为DONE_IN_PROC嵌入在响应中的小结构.它不是一个单独的网络数据包,因此不会浪费往返.

我认为你几乎总是可以坚持默认的计数行为而不用担心性能.但是在某些情况下,事先计算行数会影响性能,例如只向前游标.在这种情况下,NOCOUNT可能是必需的.除此之外,绝对没有必要遵循"尽可能使用NOCOUNT"的座右铭.

以下是关于SET NOCOUNT设置无关紧要的非常详细的分析:http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/

  • 它不是通过线路的往返延迟的字节数,这是性能杀手 (12认同)
  • 感谢您的回答.我会接受这个因为你的调查,这引起了我的更多信息和工作.我不同意开销:它可能很重要,因为其他答案显示.干杯,gbn (2认同)

Str*_*ior 84

我花了很多钱去寻找NOCOUNT附近的实际基准数据,所以我想我会分享一个简短的总结.

  • 如果您的存储过程使用游标执行大量非常快速的操作而没有返回结果,那么NOCOUNT OFF可能需要大约10倍于打开它的时间.1这是最糟糕的情况.
  • 如果您的存储过程仅执行单个快速操作而没有返回结果,则将NOCOUNT设置为ON将使性能提升约3%.2这与典型的插入或更新程序一致.
  • 如果存储过程返回结果(即您选择某些内容),则性能差异将与结果集的大小成比例减少.

  • +1对光标的影响,这与我的观察结果一致 (5认同)

Bha*_*tel 73

  • 当SET NOCOUNT为ON时,不返回计数(指示受Transact-SQL语句影响的行数).当SET NOCOUNT为OFF时,返回计数.它与任何SELECT,INSERT,UPDATE,DELETE语句一起使用.

  • SET NOCOUNT的设置在执行或运行时设置,而不是在分析时设置.

  • SET NOCOUNT ON可提高存储过程(SP)性能.

  • 语法:SET NOCOUNT {ON | 关闭}

SET NOCOUNT ON的示例:

在此输入图像描述

SET NOCOUNT OFF的示例:

在此输入图像描述

  • 使用屏幕截图轻松快速地理解.很好.:) (7认同)

mar*_*c_s 33

我想在某种程度上这是一个DBA与开发人员问题.

作为一个开发人员,我会说不要使用它,除非你绝对肯定 - 因为使用它可能会破坏你的ADO.NET代码(如微软记录的那样).

我想作为一名DBA,你会更多地在另一方面 - 尽可能使用它,除非你真的必须阻止它的使用.

此外,如果您的开发人员曾使用ADO.NET的ExecuteNonQuery方法调用返回的"RecordsAffected" ,那么如果每个人都使用,那么SET NOCOUNT ON在这种情况下,ExecuteNonQuery将始终返回0.

另见Peter Bromberg的博客文章并查看他的立场.

所以它真的归结为谁设定标准:-)


Chr*_*s J 11

如果你说你可能也有不同的客户端,如果SET NOCOUNT未设置为ON,则经典ADO会出现问题.

我经常遇到的一个问题是:如果存储过程执行了许多语句(因此返回了许多"受xxx行影响"的消息),ADO似乎不会处理这个并抛出错误"无法更改Recordset对象的ActiveConnection属性它有一个Command对象作为源."

所以我一般都主张将它设置为ON,除非有一个非常好的理由不这样做.你可能已经找到了我需要去阅读更多内容的真正原因.


Tao*_*Tao 9

冒着使事情变得更复杂的风险,我鼓励对我上面看到的所有人略有不同的规则:

  • 始终设置NOCOUNT ON在一个进程的顶部,在此之前在proc任何工作,但 总是SET NOCOUNT OFF再次,从存储过程返回记录集的任何之前.

所以"通常保持nocount,除非你实际返回结果集".我不知道这会破坏任何客户端代码的任何方式,这意味着客户端代码永远不需要了解有关proc内部的任何信息,并且它并不特别繁重.


zvo*_*kov 5

关于打破NHibernate的触发器,我亲身体验过这种体验.基本上,当NH执行UPDATE时,它会受到一定数量的行影响.通过将SET NOCOUNT ON添加到触发器,您可以将行数返回到NH预期的范围,从而解决问题.所以是的,如果你使用NH,我肯定会建议将其关闭.

关于SP中的使用,这是个人偏好的问题.我总是关掉行数,但话说再说,无论如何都没有真正强烈的争论.

另外一点,你应该考虑从基于SP的架构转移,然后你甚至不会有这个问题.

  • 关于SP vs no-SP,它已经完成了死亡...... ;-) (7认同)

归档时间:

查看次数:

252776 次

最近记录:

6 年,1 月 前