Database
 sql >> Base de Dados >  >> RDS >> Database

Surpresas e suposições de desempenho:SET NOCOUNT ON


Se você já usou o Management Studio, esta mensagem de saída provavelmente parecerá familiar:
(1 linha(s) afetada)
Isso vem do DONE_IN_PROC do SQL Server mensagem, que é enviada na conclusão bem-sucedida de qualquer instrução SQL que tenha retornado um resultado (incluindo a recuperação de um plano de execução, razão pela qual você vê duas dessas mensagens quando, na verdade, executou apenas uma única consulta).

Você pode suprimir essas mensagens com o seguinte comando:
SET NOCOUNT ON;

Por que você faria isso? Porque essas mensagens são conversas e muitas vezes inútil . Em minhas apresentações de Maus Hábitos e Práticas Recomendadas, costumo falar sobre adicionar SET NOCOUNT ON; a todos os procedimentos armazenados e ativá-lo no código do aplicativo que envia consultas ad hoc. (Durante a depuração, no entanto, você pode querer um sinalizador para ativar as mensagens novamente, pois a saída pode ser útil nesses casos.)

Eu sempre adicionei o aviso de que o conselho para ativar essa opção em todos os lugares não é universal; depende. Os conjuntos de registros ADO antigos, na verdade, os interpretavam como conjuntos de resultados, portanto, adicioná-los às consultas após o fato pode realmente interromper os aplicativos que já estão ignorando-os manualmente. E alguns ORMs (tosse NHibernate tosse ) realmente analisa os resultados para determinar o sucesso dos comandos DML (ugh!). Por favor, teste suas alterações.

Eu sei que em um ponto eu provei para mim mesmo que essas mensagens tagarelas podem afetar o desempenho, especialmente em uma rede lenta. Mas já faz muito tempo, e na semana passada Erin Stellato me perguntou se eu já tinha documentado isso formalmente. Eu não tenho, então aqui vai. Faremos um loop muito simples, onde atualizaremos uma variável de tabela um milhão de vezes:
SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

Algumas coisas que você pode notar:
  • O painel de mensagens é inundado com instâncias de (1 row(s) affected) mensagem:
  • O SELECT SYSDATETIME(); inicial não se apresenta no painel de resultados até que todo o lote seja concluído. Isso ocorre por causa das inundações.
  • Este lote levou cerca de 21 segundos para ser executado.

Agora, vamos repetir isso sem o DONE_IN_PROC mensagens, alterando SET NOCOUNT OFF; para SET NOCOUNT ON; e execute-o novamente.

Embora o painel de mensagens não tenha mais sido inundado com as mensagens afetadas pelas linhas, o lote ainda levou cerca de 21 segundos para ser executado.

Então eu pensei, espere um segundo, eu sei o que está acontecendo. Estou em uma máquina local, sem rede envolvida, usando memória compartilhada, tenho apenas SSD e montes e montes de RAM…

Então, repeti os testes usando minha cópia local do SSMS em um Banco de Dados SQL do Azure remoto – um Standard, S0, V12. Desta vez, as consultas demoraram muito mais, mesmo depois de reduzir as iterações de 1.000.000 para 100.000. Mas, novamente, não houve diferença tangível no desempenho se DONE_IN_PROC mensagens estavam sendo enviadas ou não. Ambos os lotes levaram cerca de 104 segundos e isso foi repetível em muitas iterações.

Conclusão


Durante anos, trabalhei com a impressão de que SET NOCOUNT ON; era uma parte crítica de qualquer estratégia de desempenho. Isso foi baseado em observações que fiz em, sem dúvida, uma era diferente, e que são menos prováveis ​​de se manifestar hoje.

Dito isso, continuarei usando SET NOCOUNT ON , mesmo que no hardware atual não haja diferença perceptível no desempenho. Ainda me sinto muito bem em minimizar o tráfego de rede sempre que possível. Eu deveria considerar a implementação de um teste onde eu tenha uma largura de banda muito mais restrita (talvez alguém tenha um CD AOL que possa me emprestar?), ou ter uma máquina onde a quantidade de memória seja menor que os limites de buffer de saída do Management Studio, para ter certeza de que há não é um impacto potencial nos piores cenários. Enquanto isso, embora isso não altere o desempenho percebido sobre seu aplicativo, ainda pode ajudar sua carteira sempre ativar essa opção definida, especialmente em situações como o Azure – onde você pode ser cobrado pelo tráfego de saída.