Temos um banco de dados para um produto com muita gravação. Acabamos de comprar uma nova máquina servidor com um SSD para ajudar. Para nossa surpresa, as inserções não foram mais rápidas do que em nossa máquina antiga, com armazenamento muito mais lento. Durante o benchmarking, observamos que a taxa de E / S exibida pelo processo do SQL Server era muito baixa.
Por exemplo, executei o script encontrado nesta página , exceto que adicionei um BEGIN TRAN e COMMIT ao redor do loop. Na melhor das hipóteses, eu pude ver o uso do disco atingir 7 Mb / s, enquanto a CPU mal tocou em 5%. O servidor possui 64 Gb instalados e está usando 10. O tempo total de execução foi de 2 minutos e 15 segundos na primeira chamada, até cerca de 1 minuto nas chamadas subseqüentes. O banco de dados está em recuperação simples e ficou inativo durante o teste. Larguei a mesa entre cada ligação.
Por que um script tão simples é tão lento? O hardware mal está sendo usado. As ferramentas dedicadas de benchmarking de disco e o SQLIO indicam que o SSD funciona corretamente com velocidades acima de 500 Mb / s para leitura e gravação. Entendo que as gravações aleatórias são mais lentas que as sequenciais, mas eu esperaria que uma inserção simples como essa, em uma tabela sem indexação em cluster, fosse muito mais rápida.
Por fim, nosso cenário é muito mais complexo, mas sinto que preciso entender um caso simples primeiro. Em poucas palavras, nosso aplicativo exclui dados antigos, depois usa SqlBulkCopy para copiar novos dados para tabelas temporárias, realiza alguma filtragem e, finalmente, usa MERGE e / ou INSERT INTO, dependendo dos casos para copiar os dados para as tabelas finais.
-> EDIÇÃO 1: segui o procedimento vinculado por Martin Smith e obtive o seguinte resultado:
[Wait Type] [Wait Count] [Total Wait (ms)] [T. Resource Wait (ms)] [T. Signal Wait (ms)]
NETWORK_IO 5008 46735 46587 148
LOGBUFFER 901 5994 5977 17
PAGELATCH_UP 40 866 865 1
SOS_SCHEDULER_YIELD 53279 219 121 98
WRITELOG 5 145 145 0
PAGEIOLATCH_UP 4 58 58 0
LATCH_SH 5 0 0 0
Acho estranho que o NETWORK_IO leve a maior parte do tempo, considerando que não há resultado a ser exibido nem dados a serem transferidos para outro lugar além dos arquivos SQL. O tipo NETWORK_IO inclui todas as E / S?
-> EDIÇÃO 2: Criei um disco RAM de 20Gb e montei um banco de dados a partir daí. O melhor tempo que tive no SSD é de 48 anos, com o disco RAM que caiu para 37 segundos. NETWORK_IO ainda é a maior espera. A velocidade máxima de gravação no disco RAM foi de cerca de 250 Mb / s, enquanto é capaz de executar vários gigabytes por segundo. Ainda não estava usando muita CPU, então o que está segurando o SQL?
NETWORK_IO
poderia ser a 3 milhões "1 row (s) afetada" mensagens sendo enviadas de volta. Você tentou adicionar SET NOCOUNT ON
ao script?
EE_WaitStats*.xel
para que os antigos contaminem seus resultados.
SET NOCOUNT ON
a isso também.