O banco de dados de nossos produtos contém uma tabela de trilha de auditoria:
CREATE TABLE gn_AuditTable(
gn_ObjectId int NULL,
gn_Action smallint NULL,
gn_Time datetime NULL,
gn_UserId int NULL,
gn_Login varbinary(16) NULL,
gn_ExtraObjectId int NULL,
gn_ExtraInfo int NULL
) ON [PRIMARY]
Adicionamos linhas a esta tabela com uma insert
instrução simples - sem procedimentos armazenados:
insert into gn_AuditTable (
gn_ObjectId,gn_Time,gn_UserId,gn_Login,gn_Action,gn_ExtraObjectId,gn_ExtraInfo
) values (
?,?,?,?,?,?,?
)
passando os valores das colunas como parâmetros para a consulta; também não há gatilhos.
O problema é que às vezes essa inserção é super lenta - levando em alguns casos mais de 30 segundos e esgotando o tempo.
Temos várias instalações do mesmo produto e estamos enfrentando o problema em algumas delas, mas não em todas.
A tabela de auditoria pode ser bastante grande - até alguns milhões de linhas. A inserção muito lenta acontece com bancos de dados que possuem tabelas grandes (naturalmente) - mas temos outros bancos de dados com número semelhante de linhas que funcionam bem, e mesmo os bancos de dados com o problema o apresentam de forma intermitente, na maioria dos casos a inserção é razoavelmente rápida ( subsegundo).
A tabela tem 6 índices não clusterizados e não exclusivos:
gn_Login
;gn_ObjectId
;gn_Action
egn_ExtraInfo
;gn_ExtraObjectId
;gn_Time
;gn_UserId
.
Ter todos esses índices pode causar o problema, mas, novamente, temos os mesmos índices em todos os lugares e o problema apenas em algum lugar/às vezes.
Tivemos o tempo limite de inserção pelo menos uma vez em um banco de dados de teste com apenas um usuário, portanto, o problema não parece estar relacionado à carga geral, mas à inserção e à própria tabela.
Costumávamos ter um índice clusterizado em gn_ObjectId
, mas nos livramos dele como uma tentativa de resolver esse problema. gn_ObjectId
não é sequencial e, portanto, pensamos que é uma escolha ruim para um índice clusterizado, forçando o SQL Server a reordenar as linhas nas inserções. Provavelmente gn_Time
- que está sempre aumentando - seria uma escolha melhor.
Não há chave primária porque não há coluna ou combinação de colunas que seja 'naturalmente' única - teríamos que adicionar uma coluna de id e parece apenas uma sobrecarga.
Alguém tem alguma sugestão sobre o que poderíamos olhar para diagnosticar o problema? O que é uma insert
ação que pode levar tanto tempo - de forma intermitente?