Tenemos un proceso que genera un informe de inventario. En el lado del cliente, el proceso se divide en un número configurable de subprocesos de trabajo para generar una porción de datos para el informe que corresponde a un almacén de muchos (potencialmente miles, generalmente docenas). Cada subproceso de trabajo llama a un servicio web que ejecuta un procedimiento almacenado.
El proceso de la base de datos para procesar cada fragmento reúne un conjunto de datos en una tabla #Temporary. Al final de cada fragmento de procesamiento, los datos se escriben en una tabla permanente en tempdb. Finalmente, al final del proceso, un hilo en el lado del cliente solicita todos los datos de la tabla temporal tempdb.
Cuantos más usuarios ejecuten este informe, más lento será. Analicé la actividad en la base de datos. En un momento, vi 35 solicitudes separadas, todas bloqueadas en un punto del proceso. Todos estos SPID tenían del orden de 50 ms esperas de tipo LATCH_EX
en recurso METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
. Un SPID tiene este recurso, y todos los demás están bloqueando. No encontré nada sobre este recurso de espera en una búsqueda web.
La tabla en tempdb que estamos usando tiene una IDENTITY(1,1)
columna. ¿Están estos SPID esperando la columna IDENTIDAD? ¿Qué métodos podríamos usar para reducir o eliminar el bloqueo?
El servidor es parte de un clúster. El servidor ejecuta SQL Server 2012 Standard Edition SP1 de 64 bits en Windows 2008 R2 Enterprise de 64 bits. El servidor tiene 64 GB de RAM y 48 procesadores, pero la base de datos solo puede usar 16 porque es la edición estándar.
(Tenga en cuenta que no estoy entusiasmado con el diseño de usar una tabla permanente en tempdb para contener todos estos datos. Cambiar eso sería un desafío técnico y político interesante, pero estoy abierto a sugerencias).
ACTUALIZACIÓN 23/04/2013
Hemos abierto un caso de soporte con Microsoft. Mantendré esta pregunta actualizada a medida que aprendamos más.
ACTUALIZACIÓN 10/05/2013
El ingeniero de soporte de SQL Server acordó que las esperas fueron causadas por la columna IDENTIDAD. Eliminar la IDENTIDAD eliminó las esperas. No pudimos duplicar el problema en SQL 2008 R2; ocurrió solo en SQL 2012.