ESTABLECER NOCOUNT EN el uso


Inspirado por esta pregunta donde hay diferentes puntos de vista sobre el CONJUNTO NOCOUNT...

¿Deberíamos usar SET NOCOUNT ON para SQL Server? Si no, ¿por qué no?

Lo que hace Editar 6, el 22 de julio de 2011

Suprime el mensaje "xx rows affected" después de cualquier DML. Este es un conjunto de resultados y cuando se envía, el cliente debe procesarlo. Es pequeño, pero medible (ver respuestas abajo)

Para los disparadores, etc., el cliente recibirá múltiples filas " xx afectado " y esto causa todo tipo de errores para algunos OR, MS Access, JPA, etc (ver ediciones a continuación)

Antecedentes:

La mejor práctica general aceptada (pensé hasta esta pregunta) es usar SET NOCOUNT ON en disparadores y procedimientos almacenados en SQL Server. Lo usamos en todas partes y un rápido Google muestra un montón de MVP de SQL Server de acuerdo también.

MSDN dice que esto puede romper un .net SqlDataAdapter.

Ahora, esto significa para mí que el SqlDataAdapter es limitado simplemente procesar CRUD porque espera que el mensaje" n filas afectadas " coincida. Por lo tanto, no puedo usar:

  • SI EXISTE para evitar duplicados (sin mensaje de filas afectadas) Nota: use con precaución
  • DONDE NO EXISTE (menos filas entonces esperadas
  • Filtrar actualizaciones triviales (por ejemplo, no hay datos realmente cambia)
  • Haga cualquier acceso a la tabla antes (como el registro)
  • Ocultar complejidad o desnormlización
  • etc

En la pregunta marc_s (que conoce sus cosas SQL) dice que no lo use. Esto difiere de lo que pienso (y me considero algo competente en SQL también).

Es posible que me esté perdiendo algo (siéntase libre de señalar lo obvio), pero ¿qué piensan ustedes por ahí?

Nota: han pasado años desde que vi este error porque no uso SqlDataAdapter hoy en día.

Ediciones después de comentarios y preguntas:

Editar: Más pensamientos...

Tenemos varios clientes: uno puede usar un SQLDataAdaptor de C#, otro puede usar NHibernate de Java. Estos pueden verse afectados de diferentes maneras con SET NOCOUNT ON.

Si considera los procs almacenados como métodos, entonces es una mala forma (anti-patrón) asumir que algún procesamiento interno funciona de cierta manera para sus propios fines.

Edit 2: a trigger breaking NHibernate question , donde SET NOCOUNT ON no se puede establecer

(y no, no es un duplicado de este)

Editar 3: Aún más información, gracias a mi MVP colleague

Editar 4: 13 de mayo de 2011

Rompe Linq 2 SQL también cuando no se especifica?

Editar 5: 14 Jun 2011

Rompe JPA, proc almacenado con variables de tabla: ¿JPA 2.0 soporta variables de tabla de SQL Server?

Editar 6: 15 Ago 2011

La cuadrícula de datos SSMS "Editar filas" requiere ESTABLECER NOCOUNT ON: Activador de actualización con GRUPO POR

Editar 7: 07 Mar 2013

Más detalles en profundidad de @RemusRusanu:
¿Establecer NOCOUNT EN realmente hacer que gran parte de una diferencia de rendimiento

Author: gbn, 2009-09-27

12 answers

Ok ahora que he hecho mi investigación, aquí está el trato:

En el protocolo TDS, SET NOCOUNT ON solo guarda 9 bytes por consulta mientras que el texto "SET NOCOUNT ON" en sí es la friolera de 14 bytes. Solía pensar que 123 row(s) affected se devolvía desde el servidor en texto plano en un paquete de red separado, pero ese no es el caso. De hecho, es una pequeña estructura llamada DONE_IN_PROC incrustada en la respuesta. No es un paquete de red separado, por lo que no se desperdician viajes de ida y vuelta.

Creo que puedes seguir contando por defecto comportamiento casi siempre sin preocuparse por el rendimiento. Sin embargo, hay algunos casos en los que calcular el número de filas de antemano afectaría el rendimiento, como un cursor solo hacia adelante. En ese caso, NO contar podría ser una necesidad. Aparte de eso, no hay absolutamente ninguna necesidad de seguir el lema "usar NOCOUNT siempre que sea posible".

Aquí hay un análisis muy detallado sobre la insignificancia del ajuste SET NOCOUNT : http://daleburnett.com/2014/01/everything-ever-wanted-know-set-nocount /

 169
Author: Sedat Kapanoglu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-19 21:24:02

Me llevó mucho investigar para encontrar cifras reales de referencia alrededor de NOCOUNT, así que pensé en compartir un breve resumen.

  • Si su procedimiento almacenado utiliza un cursor para realizar muchas operaciones muy rápidas sin resultados devueltos, tener NOCOUNT APAGADO puede tomar aproximadamente 10 veces más que tenerlo ACTIVADO. 1 Este es el peor de los casos.
  • Si su procedimiento almacenado solo realiza una sola operación rápida sin resultados devueltos, al establecer NOCOUNT ON se rendimiento alrededor de un aumento de rendimiento del 3%. 2 Esto sería coherente con un procedimiento típico de inserción o actualización.
  • Si su procedimiento almacenado devuelve resultados (es decir, selecciona algo), la diferencia de rendimiento disminuirá proporcionalmente con el tamaño del conjunto de resultados.
 74
Author: StriplingWarrior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-29 21:13:52
  • Cuando SET NOCOUNT está ACTIVADO, no se devuelve el recuento (que indica el número de filas afectadas por una instrucción Transact-SQL). Cuando SET NOCOUNT está DESACTIVADO, se devuelve el recuento. Se utiliza con cualquier instrucción SELECT, INSERT, UPDATE, DELETE.

  • La configuración de SET NOCOUNT se establece en tiempo de ejecución o ejecución y no en tiempo de análisis.

  • ESTABLECER NOCOUNT ON mejora el rendimiento del procedimiento almacenado (SP).

  • Sintaxis: SET NOCOUNT { ON / OFF }

Ejemplo de SET NOCOUNT ON:

introduzca la descripción de la imagen aquí

Ejemplo de SET NOCOUNT OFF:

introduzca la descripción de la imagen aquí

 49
Author: Bhaumik Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-14 16:20:26

Supongo que hasta cierto punto es un problema de DBA vs.desarrollador.

Como desarrollador en su mayoría, diría que no lo use a menos que sea absolutamente necesario, porque usarlo puede romper su ADO.NET código (según lo documentado por Microsoft).

Y supongo que como DBA, estaría más en el otro lado: úselo siempre que sea posible a menos que realmente deba evitar su uso.

También, si sus desarrolladores alguna vez usan los "RecordsAffected" que devuelven ADO.NET 's ExecuteNonQuery método de llamada, usted está en problemas si todo el mundo usa SET NOCOUNT ON ya que en este caso, ExecuteNonQuery siempre devolverá 0.

También ver la entrada del blog de Peter Bromberg y echa un vistazo a su posición.

Así que todo se reduce a quién establece los estándares: -)

Marc

 29
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-27 14:56:24

Si estás diciendo que también podrías tener diferentes clientes, hay problemas con classic ADO si SET NOCOUNT no está ACTIVADO.

Uno que experimento regularmente: si un procedimiento almacenado ejecuta un número de instrucciones (y por lo tanto se devuelven un número de mensajes "xxx filas afectadas"), ADO parece no manejar esto y lanza el error "No se puede cambiar la propiedad ActiveConnection de un objeto Recordset que tiene un objeto Command como su fuente."

Así que generalmente abogo activarlo a menos que haya una realmente realmente buena razón para no hacerlo. es posible que haya encontrado la muy, muy buena razón por la que necesito ir y leer más.

 11
Author: Chris J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-13 15:52:00

A riesgo de complicar las cosas, recomiendo una regla ligeramente diferente a todas las que veo arriba:

  • Siempre establezca NOCOUNT ON en la parte superior de un proc, antes de hacer cualquier trabajo en el proc, pero también siempre SET NOCOUNT OFF de nuevo, antes de devolver cualquier conjunto de registros del proc almacenado.

Así que "por lo general no se debe contar, excepto cuando realmente se está devolviendo un conjunto de resultados". No conozco ninguna manera de que esto pueda romper cualquier código de cliente, significa que el código de cliente nunca necesita saber algo sobre los internos del proc, y no es particularmente oneroso.

 9
Author: Tao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-22 11:03:56

Con respecto a los desencadenantes que rompen NHibernate, tuve esa experiencia de primera mano. Básicamente, cuando NH hace una ACTUALIZACIÓN espera cierto número de filas afectadas. Al agregar SET NOCOUNT a los disparadores, obtiene el número de filas de nuevo a lo que NH esperaba, solucionando así el problema. Así que sí, definitivamente recomendaría apagarlo para los disparadores si usas NH.

Con respecto al uso en SPs, es una cuestión de preferencia personal. Siempre había apagado el conteo de filas, pero de nuevo, no hay argumentos fuertes de ninguna manera.

En una nota diferente, realmente debería considerar alejarse de la arquitectura basada en SP, entonces ni siquiera tendrá esta pregunta.

 5
Author: zvolkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-11 22:37:01

ESTABLECER NOCOUNT ON; El código anterior detendrá el mensaje generado por sql server engine en la ventana de resultados fronted después de la ejecución del comando DML / DDL.

¿por Qué lo hacemos? Como SQL server engine toma algún recurso para obtener el estado y generar el mensaje, se considera una sobrecarga para Sql server engine.So activamos el mensaje sin contar.

 1
Author: Subhransu Panda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-18 17:34:56

No se como probar SET NOCOUNT ON entre cliente y SQL, así que probé un comportamiento similar para otro comando SET "SET TRANSACTION ISOLATION LEVEL READ UNIMMITTED"

Envié un comando desde mi conexión cambiando el comportamiento predeterminado de SQL (READ COMMITTED), y se cambió para los siguientes comandos. Cuando cambié el nivel de AISLAMIENTO dentro de un procedimiento almacenado, no cambió el comportamiento de conexión para el siguiente comando.

Actual conclusión,

  1. Cambiar la configuración dentro del procedimiento almacenado no cambia la configuración predeterminada de la conexión.
  2. Cambiar la configuración enviando comandos usando ADOConnection cambia el comportamiento predeterminado.

Creo que esto es relevante para otro comando SET como "SET NOCOUNT ON"

 0
Author: Rabia Mansour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-17 06:51:32
SET NOCOUNT ON;

Esta línea de código se utiliza en SQL para no devolver las filas numéricas afectadas en la ejecución de la consulta. Si no requerimos el número de filas afectadas, podemos usar esto ya que esto ayudaría a ahorrar uso de memoria y aumentar la velocidad de ejecución de la consulta.

 0
Author: user1509,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-17 09:01:40

If (set no count== off)

{ a continuación, mantendrá los datos de cuántos registros afectados así que reduce el rendimiento } else { no rastreará el registro de cambios por lo tanto mejorar el rendimiento } }

 0
Author: Shubham Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-08 11:26:01

Sé que es una pregunta muy vieja. pero solo para actualizar.

La mejor manera de usar "SET NOCOUNT ON" es colocarlo como primera instrucción en su SP y activarlo de nuevo justo antes de la última instrucción SELECT.

 0
Author: KRules,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-05 11:30:24