Sql 不计算使用量
灵感来源于对布景的不同看法 我们应该为SQL Server使用SET NOCOUNT ON吗?若否,原因为何 它的功能编辑6,2011年7月22日 它会在任何DML之后抑制“xx行受影响”消息。这是一个结果集,发送时,客户端必须对其进行处理。它很小,但可以测量(见下面的答案) 对于触发器等,客户端将收到多个“受影响的xx行”,这会导致某些ORM、MS Access、JPA等的各种错误(请参见下面的编辑) 背景: 一般公认的最佳实践(我一直认为在这个问题之前)是在SQL Server中的触发器和存储过程中使用Sql 不计算使用量,sql,sql-server,tsql,ado.net,concurrency,Sql,Sql Server,Tsql,Ado.net,Concurrency,灵感来源于对布景的不同看法 我们应该为SQL Server使用SET NOCOUNT ON吗?若否,原因为何 它的功能编辑6,2011年7月22日 它会在任何DML之后抑制“xx行受影响”消息。这是一个结果集,发送时,客户端必须对其进行处理。它很小,但可以测量(见下面的答案) 对于触发器等,客户端将收到多个“受影响的xx行”,这会导致某些ORM、MS Access、JPA等的各种错误(请参见下面的编辑) 背景: 一般公认的最佳实践(我一直认为在这个问题之前)是在SQL Server中的触发器和存
SET NOCOUNT ON
。我们在任何地方都使用它,谷歌的快速搜索显示很多SQL Server MVP也同意这一点
MSDN说这可以打破一个错误
现在,这对我来说意味着SQLDataAdapter仅限于CRUD处理,因为它希望“n行受影响”消息匹配。所以,我不能使用:
- 如果存在以避免重复(没有行受影响的消息)注意:小心使用
- 不存在的位置(比预期的行少
- 过滤掉琐碎的更新(例如没有数据实际更改)
- 执行任何表访问之前(如日志记录)
- 隐藏复杂性或去规范化
- 等
设置NOCOUNT ON
可以以不同的方式影响这些客户机
如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的工作是不正确的(反模式)
编辑2:a,其中SET NOCOUNT ON
无法设置
(不,它不是的副本)
编辑3:更多信息,感谢我的MVP同事
- ,问题导致SQL 2000及更早版本上的断开连接
来自@RemusRusanu的更深入的细节:
我想在某种程度上这是DBA与开发者之间的问题 作为一个开发人员,我要说的是,除非你绝对必须使用它,否则不要使用它——因为使用它会破坏你的ADO.NET代码(正如微软所记录的) 我想作为一名DBA,你会更倾向于另一方——尽可能地使用它,除非你真的必须阻止它的使用 此外,如果开发人员使用ADO.NET的
ExecuteOnQuery
方法调用返回的“RecordsAffected”,那么如果每个人都使用SET NOCOUNT ON
,您就会遇到麻烦,因为在这种情况下,ExecuteOnQuery将始终返回0
也可以去看彼得·布罗姆伯格,看看他的位置
因此,这实际上可以归结为谁来制定标准:-)
马克好的,现在我已经完成了我的研究,以下是交易: 在TDS协议中,
SET NOCOUNT-ON
仅保存,而文本“SET NOCOUNT-ON”本身的大小高达14字节。我过去认为受影响的123行
是在单独的网络数据包中以明文形式从服务器返回的,但事实并非如此。实际上,它是一个嵌入在响应中的名为DONE\u in\u PROC
的小结构。它不是一个单独的网络数据包,因此不会浪费往返时间
我认为您几乎可以始终坚持默认计数行为,而不必担心性能。但是,在某些情况下,预先计算行数会影响性能,例如仅向前游标。在这种情况下,可能不需要计算。除此之外,绝对没有必要遵循“尽可能使用NOCOUNT”的座右铭
这里有一个非常详细的分析,说明了设置NOCOUNT的重要性:关于破坏NHibernate的触发器,我有第一手的经验。基本上,当NH进行更新时,它希望有一定数量的行受到影响。通过将SETNOCOUNT添加到触发器,您可以将行数恢复到NH预期的值,从而解决问题。所以是的,如果你使用NH,我绝对建议关闭触发器 关于SPs中的使用,这是个人偏好的问题。我总是把排数关上,但不管怎样,都没有真正有力的论据
在一个不同的注释中,你真的应该考虑远离基于SP的体系结构,那么你甚至不会有这个问题。
< P>如果你也说你可能有不同的客户端,如果没有设置NoCube,那么经典的ADO存在问题。p> 我经常遇到的一个问题是:如果存储过程执行许多语句(从而返回许多“受影响的xxx行”消息),ADO似乎无法处理这一问题,并抛出错误“无法更改以命令对象为源的记录集对象的ActiveConnection属性”所以我通常主张把它打开,除非有很好的理由不这样做。你可能已经找到了一个非常好的理由,我需要深入阅读。我花了很多时间才找到NOCOUNT周围的真实基准数据,所以我想我应该分享一个简短的总结
- 如果您的存储过程使用游标执行许多非常快速的操作,并且没有返回结果,那么禁用NOCOUNT可能会导致错误
SET NOCOUNT ON;
CREATE PROCEDURE NoCountOn AS set nocount on DECLARE @num INT = 10000 while @num > 0 begin update MyTable SET SomeColumn=SomeColumn set @num = @num - 1 end GO CREATE PROCEDURE NoCountOff AS set nocount off DECLARE @num INT = 10000 while @num > 0 begin update MyTable SET SomeColumn=SomeColumn set @num = @num - 1 end GO
SET NOCOUNT ON DECLARE @test TABLE (ID int) INSERT INTO @test VALUES (1),(2),(3) DECLARE @affectedRows int = -99 DELETE top (1) FROM @test SET @affectedRows = @@rowcount SELECT @affectedRows as affectedRows