Optimización: mover declaraciones de variables a la parte superior de su procedimiento

15

Mientras trabajaba en la optimización de algunos procedimientos almacenados, me senté con el DBA y revisé algunos procedimientos almacenados con un alto bloqueo y / o una alta actividad de lectura / escritura.

Una cosa que mencionó el DBA fue que debería declarar todas las variables (especialmente TABLElas) en la parte superior del procedimiento almacenado para evitar recompilaciones.

Esta es la primera vez que oigo hablar de esto y estaba buscando alguna confirmación antes de volver a visitar todos los diferentes procedimientos almacenados que tenemos. Lo llamaba "visualización tardía del código", y la recompilación estaba bloqueando el esquema que explicaría el bloqueo.

¿Mover todas las declaraciones de variables a la parte superior de su procedimiento almacenado reduce las recompilaciones?

brad.v
fuente

Respuestas:

18

No.

Esto solía ser cierto hace mucho tiempo (y ya no lo es, al menos desde SQL Server 2000), o nunca fue cierto y su DBA simplemente confundió su recomendación con la siguiente :

Es importante agrupar todas las instrucciones DDL (como crear índices) para tablas temporales al comienzo de un procedimiento almacenado. Al colocar estas declaraciones DDL juntas, se pueden evitar compilaciones innecesarias debido al cambio de esquema.

Puede encontrar otra explicación del razonamiento detrás de esta recomendación en esta página .

Si echamos un vistazo a este KB de Microsoft , vemos que la causa de la recompilación de un procedimiento almacenado puede ser una de las siguientes (SQL Server 2005+):

  1. Esquema cambiado.
  2. Estadísticas cambiadas.
  3. Recompilar DNR.
  4. Establecer opción modificada.
  5. La tabla temporal ha cambiado.
  6. Conjunto de filas remotas cambiado.
  7. Para permisos de navegación cambiados.
  8. El entorno de notificación de consulta cambió.
  9. La vista MPI ha cambiado.
  10. Opciones de cursor cambiadas.
  11. Con opción de recompilación.

Declarar una variable, incluso una variable de tabla (es decir @table_variable), no puede desencadenar ninguno de estos eventos, obviamente, porque declarar una variable no cuenta como DDL . Una variable (incluso una variable de tabla) es un objeto temporal utilizado exclusivamente para su programación T-SQL. Es por eso que las variables de tabla no obtienen estadísticas y no están vinculadas por transacciones . Declarar una variable (tabla o no) no puede desencadenar una recompilación de proceso.

#temp_tableSin embargo, crear una tabla temporal (es decir ) o un índice es un DDL que afecta la definición física de la base de datos. Las tablas e índices temporales son objetos "reales" con estadísticas y control transaccional, por lo tanto, crearlos podría activar cualquiera de los eventos 1, 2 o 5 en la lista anterior y, por lo tanto, desencadenar una recompilación de proceso.

Nick Chammas
fuente
3

No debería hacer una diferencia o reducir los bloqueos de compilación o causar menos recompilaciones para declarar una variable a la mitad de la pila o en la parte superior. Por casualidad, hago esto en la parte superior para facilitar la lectura.

Para llegar a la parte de la pregunta "¿en qué está pensando mi DBA?", Lo único que se me ocurre (aparte del punto de Nick de que están pensando cómo solía ser algo) es que tal vez estaban hablando del olfateo de parámetros (ver Opción 2 en este enlace sobre charla simple)

Acerca de su bloqueo -> Si está viendo un verdadero bloqueo, ese no es el tipo de contención de bloqueo de compilación del que su DBA está hablando más probablemente. Si bien es cierto que hay ciertas cosas que afectan esto (no las tablas de calificación de esquema, no la calificación de esquema de sus llamadas de procedimiento almacenado, por ejemplo), esta no es la causa de sus lecturas altas ciertamente y probablemente no sea la causa de su bloqueo. Definitivamente debe hacer todo lo posible para evitar estos bloqueos de compilación. Pero consideraría ajustar y optimizar el resto del código de procedimiento almacenado como una tarea más importante que preocuparse por dónde están las variables. También puede leer Cómo identificar y resolver bloqueos de compilación si desea verificar que no está experimentando problemas aquí.

Publique esos ejemplos de antes / después y veremos qué está conduciendo el DBA aquí.

Mike Walsh
fuente