Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SET NOCOUNT ON usage

People also ask

Do I need to set Nocount off?

Now, is set nocount off necessary? No, as any new commands executed will be in a different scope, and by default set nocount off is always in effect. But as stated above in comments, it's considered a good practice, just to explicitly indicate that this setting will return to normal when the proc is finished executing.

What is the use of set Ansi_nulls ON GO SET Quoted_identifier on go?

When a stored procedure is created, the SET QUOTED_IDENTIFIER and SET ANSI_NULLS settings are captured and used for subsequent invocations of that stored procedure. When executed inside a stored procedure, the setting of SET QUOTED_IDENTIFIER is not changed. When SET ANSI_DEFAULTS is ON, QUOTED_IDENTIFIER is also ON.

What is set Nocount on in MySQL?

The SET NOCOUNT ON stops the message indicating the number of rows affected by a Transact-SQL statement from being returned as part of the results. MySQL doesn't report the number of rows affected by a query, therefore there's no such function.

What does set Ansi_nulls on mean?

When ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN. When SET ANSI_NULLS is OFF, comparisons of all data against a null value evaluate to TRUE if the data value is NULL. If SET ANSI_NULLS is not specified, the setting of the ANSI_NULLS option of the current database applies.


Ok now I've done my research, here is the deal:

In TDS protocol, SET NOCOUNT ON only saves 9-bytes per query while the text "SET NOCOUNT ON" itself is a whopping 14 bytes. I used to think that 123 row(s) affected was returned from server in plain text in a separate network packet but that's not the case. It's in fact a small structure called DONE_IN_PROC embedded in the response. It's not a separate network packet so no roundtrips are wasted.

I think you can stick to default counting behavior almost always without worrying about the performance. There are some cases though, where calculating the number of rows beforehand would impact the performance, such as a forward-only cursor. In that case NOCOUNT might be a necessity. Other than that, there is absolutely no need to follow "use NOCOUNT wherever possible" motto.

Here is a very detailed analysis about insignificance of SET NOCOUNT setting: http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount/


It took me a lot of digging to find real benchmark figures around NOCOUNT, so I figured I'd share a quick summary.

  • If your stored procedure uses a cursor to perform a lot of very quick operations with no returned results, having NOCOUNT OFF can take roughly 10 times as long as having it ON. 1 This is the worst-case scenario.
  • If your stored procedure only performs a single quick operation with no returned results, setting NOCOUNT ON might yield around a 3% performance boost. 2 This would be consistent with a typical insert or update procedure. (See the comments on this answer for some discussion about why this may not always be faster.)
  • If your stored procedure returns results (i.e. you SELECT something), the performance difference will diminish proportionately with the size of the result set.

  • When SET NOCOUNT is ON, the count (indicating the number of rows affected by a Transact-SQL statement) is not returned. When SET NOCOUNT is OFF, the count is returned. It is used with any SELECT, INSERT, UPDATE, DELETE statement.

  • The setting of SET NOCOUNT is set at execute or run time and not at parse time.

  • SET NOCOUNT ON improves stored procedure (SP) performance.

  • Syntax: SET NOCOUNT { ON | OFF }

Example of SET NOCOUNT ON:

enter image description here

Example of SET NOCOUNT OFF:

enter image description here


I guess to some degree it's a DBA vs. developer issue.

As a dev mostly, I'd say don't use it unless you absolutely positively have to - because using it can break your ADO.NET code (as documented by Microsoft).

And I guess as a DBA, you'd be more on the other side - use it whenever possible unless you really must prevent it's usage.

Also, if your devs ever use the "RecordsAffected" being returned by ADO.NET's ExecuteNonQuery method call, you're in trouble if everyone uses SET NOCOUNT ON since in this case, ExecuteNonQuery will always return 0.

Also see Peter Bromberg's blog post and check out his position.

So it really boils down to who gets to set the standards :-)

Marc


If you're saying you might have different clients as well, there are problems with classic ADO if SET NOCOUNT is not set ON.

One I experience regularly: if a stored procedure executes a number of statements (and thus a number of "xxx rows affected" messages are returned), ADO seems not to handle this and throws the error "Cannot change the ActiveConnection property of a Recordset object which has a Command object as its source."

So I generally advocate setting it ON unless there's a really really good reason not to. you may have found the really really good reason which I need to go and read into more.


At the risk of making things more complicated, I encourage a slightly different rule to all those I see above:

  • Always set NOCOUNT ON at the top of a proc, before you do any work in the proc, but also always SET NOCOUNT OFF again, before returning any recordsets from the stored proc.

So "generally keep nocount on, except when you are actually returning a resultset". I don't know any ways that this can break any client code, it means client code never needs to know anything about the proc internals, and it isn't particularly onerous.


Regarding the triggers breaking NHibernate, I had that experience first-hand. Basically, when NH does an UPDATE it expects certain number of rows affected. By adding SET NOCOUNT ON to the triggers you get the number of rows back to what NH expected thereby fixing the issue. So yeah, I would definitely recommend turning it off for triggers if you use NH.

Regarding the usage in SPs, it's a matter of personal preference. I had always turned the row count off, but then again, there are no real strong arguments either way.

On a different note, you should really consider moving away from SP-based architecture, then you won't even have this question.