Programar tareas o lotes en SQL Server

Cada instancia de SQL Server es un proceso independiente del sistema operativo. Cada instancia tiene que controlar miles de solicitudes simultáneas de los usuarios. Las instancias de SQL Server utilizan subprocesos de Microsoft Windows o, si están configuradas, fibras, para administrar estas tareas simultáneas de manera eficaz. Cada instancia de SQL Server ejecuta siempre varios subprocesos para procesos del sistema. Esto incluye uno o varios subprocesos para cada biblioteca de red del servidor, un subproceso de red para controlar la E/S de red y un subproceso de señales para comunicarse con el Administrador de control de servicios.

Descripción de la programación

Cada instancia de SQL Server tiene un nivel interno que implementa un entorno similar a un sistema operativo. Este nivel interno se utiliza para la programación y sincronización de tareas simultáneas sin tener que llamar al kernel de Windows. También puede programar fibras o subprocesos de Windows de forma eficaz. Cada instancia de SQL Server mantiene un grupo de fibras o subprocesos de Windows para procesar las consultas del usuario. El tamaño máximo de este grupo se controla mediante la opción de configuración del servidor max worker threads.

Para comprender cómo se procesa una solicitud o tarea, le será de ayuda entender los siguientes términos básicos:

  • conexión
    Se establece una conexión cuando el usuario inicia una sesión correctamente. A continuación, el usuario puede enviar una o varias instrucciones de Transact-SQL para ejecutarse. Una conexión se cierra cuando el usuario la cierra explícitamente o cuando se termina.

  • lote
    Un lote SQL es un conjunto de una o varias instrucciones de Transact-SQL enviadas desde un cliente a una instancia de SQL Server para ejecutarse. Representa una unidad de trabajo enviada por los usuarios al Database Engine (Motor de base de datos).

  • tarea
    Una tarea representa una unidad de trabajo programada por SQL Server. Un lote puede estar asignado a una o varias tareas. Por ejemplo, una consulta en paralelo será ejecutada por varias tareas.

  • Subproceso de Windows
    Cada subproceso de Windows representa un mecanismo de ejecución independiente.

  • fibra
    Una fibra es un subproceso ligero que requiere menos recursos que un subproceso de Windows y que puede cambiar el contexto en el modo de usuario. Un subproceso de Windows se puede asignar a varias fibras.

  • subproceso de trabajo
    Un subproceso de trabajo representa un subproceso lógico en SQL Server asignado internamente (1:1) a un subproceso de Windows o, si se ha seleccionado el valor ON para lightweight pooling, a una fibra. La asignación se mantiene hasta que se cancela la asignación del subproceso de trabajo a causa de presión de memoria o porque ha estado inactiva durante un tiempo prolongado. La asociación entre una tarea y un subproceso de trabajo se mantiene a lo largo de la duración de la tarea.

Administrar conexiones de usuario y recursos de subprocesos de trabajo

Aunque los subprocesos y las fibras utilizan los recursos de manera moderada, los consumen. En sistemas con cientos o miles de conexiones de usuario que tienen un subproceso de trabajo por conexión, el consumo de recursos puede reducir la eficacia de SQL Server. Sin embargo, no es necesario asignar un subproceso de trabajo dedicado para cada conexión de usuario, pues la mayoría de las conexiones en realidad pasan gran parte del tiempo esperando la recepción de los lotes enviados por el cliente. En cambio, la instancia de SQL Server utiliza un grupo de subprocesos de trabajo. El grupo de subprocesos de trabajo sólo debe ser lo suficientemente grande como para dar servicio al número de conexiones de usuario que ejecutan lotes al mismo tiempo en esa instancia. Si se deja la opción max worker threads con su valor predeterminado de 0, la instancia de SQL Server podrá asignar eficazmente las conexiones de usuario a varios subprocesos de trabajo. De este modo se garantiza que no consuman demasiados recursos.

Configurar SQL Server para fibras

La opción de configuración del servidor lightweight pooling controla si una instancia de SQL Server utiliza fibras o subprocesos de Windows. El valor predeterminado de esta opción es 0. Esto indica que la instancia de SQL Server programa un subproceso de Windows por subproceso de trabajo, hasta el máximo establecido en la opción max worker threads. Si se selecciona un valor de 1 para la opción lightweight pooling, SQL Server utilizará fibras en lugar de subprocesos de Windows. Esto se denomina ejecución en modo de fibra. En modo de fibra, una instancia de SQL Server asigna un subproceso de Windows por programador de SQL y, a continuación, una fibra por subproceso de trabajo, hasta alcanzar el máximo establecido en la opción max worker threads. Una instancia de SQL Server utiliza los mismos algoritmos para programar y sincronizar las tareas cuando se utilizan fibras o subprocesos de Windows. SQL Server Express no admite fibras. Para obtener más información, vea Usar la opción lightweight pooling. No se recomienda utilizar la programación en modo de fibra para un funcionamiento habitual. La razón es que puede reducir el rendimiento al eliminar las ventajas normales del cambio de contexto, y que algunos componentes de SQL Server no funcionan correctamente en modo de fibra. Para obtener más información, vea lightweight pooling.

Funcionamiento de la programación de tareas o lotes

Cuando una aplicación se conecta al Database Engine (Motor de base de datos), se le asigna un Id. de sesión (SPID). Toda la información que se debe conservar durante la conexión se administra en estructuras de datos internas asociadas al SPID. Cuando una instancia de SQL Server recibe lotes de los clientes, los divide en una o varias tareas y luego asocia cada una de ellas a un subproceso de trabajo disponible del grupo de subprocesos de trabajo. Un subproceso de trabajo está enlazado a una tarea durante toda su vigencia. Un subproceso de trabajo ejecuta la solicitud en el programador de SQL asociado. Si no hay ningún subproceso de trabajo disponible y no se ha alcanzado el valor de max worker threads, la instancia de SQL Server asignará un nuevo subproceso de trabajo al nuevo lote. Si no hay subprocesos o fibras disponibles y se ha alcanzado el valor de max worker threads, la instancia de SQL Server bloqueará la nueva tarea hasta que quede libre un subproceso de trabajo.

Una vez que un subproceso de trabajo se asocia a una tarea, permanece asociado a ella hasta que se completa, por ejemplo hasta que se devuelve al cliente el último de los conjuntos de resultados que genera el lote. En ese momento, el subproceso de trabajo se libera y puede unirse a las tareas asociadas al siguiente lote.

El Database Engine (Motor de base de datos) sólo debe realizar un trabajo de forma activa para una conexión desde el momento en el que se recibe un lote hasta que se devuelven los resultados al cliente. Es posible que durante este período haya momentos en los que el lote no requiera un procesamiento activo. Por ejemplo, puede haber momentos en los que el Database Engine (Motor de base de datos) deba esperar que una operación de lectura recupere los datos necesarios para la consulta actual o espere a que otro lote libere un bloqueo. La asociación entre una tarea y un subproceso de trabajo se mantiene incluso cuando la tarea está bloqueada en algún recurso.

Cuando el Database Engine (Motor de base de datos) empieza a procesar una tarea asociada a un lote, programa el subproceso de trabajo asociado a la tarea para que realice el trabajo. Una vez el subproceso de trabajo ha completado el trabajo para la tarea, la instancia de SQL Server distribuye el subproceso de trabajo a la siguiente tarea que está lista para trabajar. Un SPID permanece constante para una conexión a lo largo de toda su duración. En las conexiones de larga duración es posible que las tareas de lote individuales sean ejecutadas por muchos subprocesos de trabajo distintos. Por ejemplo, puede que trabajo1 ejecute las tareas del primer lote y trabajo2 las del segundo. Algunas instrucciones se pueden procesar en paralelo. En ese caso, puede que varios subprocesos de trabajo ejecuten varias tareas de un lote al mismo tiempo.