Temos um processo que gera um relatório de inventário. No lado do cliente, o processo divide um número configurável de threads de trabalho para criar uma porção de dados para o relatório que corresponde a um repositório dentre muitos (potencialmente milhares, geralmente dezenas). Cada segmento de trabalho chama um serviço da Web que executa um procedimento armazenado.
O processo do banco de dados para processar cada pedaço reúne um monte de dados em uma tabela #Temporary. No final de cada pedaço de processamento, os dados são gravados em uma tabela permanente em tempdb. Finalmente, no final do processo, um encadeamento no lado do cliente solicita todos os dados da tabela tempdb permanente.
Quanto mais usuários executam este relatório, mais lento fica. Analisei a atividade no banco de dados. Em um ponto, vi 35 solicitações separadas, todas bloqueadas em um ponto do processo. Todos esses SPIDs tiveram da ordem de 50 ms esperas do tipo LATCH_EX
no recurso METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
. Um SPID possui esse recurso e todos os outros estão bloqueando. Não encontrei nada sobre esse recurso de espera em uma pesquisa na web.
A tabela em tempdb que estamos usando possui uma IDENTITY(1,1)
coluna. Esses SPIDs estão aguardando a coluna IDENTITY? Quais métodos podemos usar para reduzir ou eliminar o bloqueio?
O servidor faz parte de um cluster. O servidor está executando o SQL Server 2012 Standard Edition SP1 de 64 bits no Windows 2008 R2 Enterprise de 64 bits. O servidor possui 64 GB de RAM e 48 processadores, mas o banco de dados pode usar apenas 16 porque é a edição padrão.
(Observe que não estou entusiasmado com o design de usar uma tabela permanente no tempdb para armazenar todos esses dados. Mudar isso seria um desafio técnico e político interessante, mas estou aberto a sugestões.)
ATUALIZAÇÃO 23/04/2013
Abrimos um caso de suporte com a Microsoft. Manteremos essa pergunta atualizada à medida que aprendermos mais.
ATUALIZAÇÃO 5/10/2013
O engenheiro de suporte do SQL Server concordou que as esperas foram causadas pela coluna IDENTITY. A remoção da IDENTITY eliminou as esperas. Não foi possível duplicar o problema no SQL 2008 R2; ocorreu apenas no SQL 2012.