AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 232816
Accepted
Joe Obbish
Joe Obbish
Asked: 2019-03-22 20:21:55 +0800 CST2019-03-22 20:21:55 +0800 CST 2019-03-22 20:21:55 +0800 CST

Por que um loop simples resulta em esperas ASYNC_NETWORK_IO?

  • 772

O seguinte T-SQL leva cerca de 25 segundos na minha máquina com SSMS v17.9:

DECLARE @outer_loop INT = 0,
@big_string_for_u VARCHAR(8000);

SET NOCOUNT ON;

WHILE @outer_loop < 50000000
BEGIN
    SET @big_string_for_u = 'ZZZZZZZZZZ';
    SET @outer_loop = @outer_loop + 1;
END;

Acumula 532 ms de ASYNC_NETWORK_IOesperas de acordo com sys.dm_exec_session_wait_statse sys.dm_os_wait_stats. O tempo total de espera aumenta à medida que o número de iterações de loop aumenta. Usando o wait_completedevento estendido, posso ver que a espera acontece aproximadamente a cada 43 ms, com algumas exceções:

mesa de espera

Além disso, posso obter as pilhas de chamadas que ocorrem logo antes da ASYNC_NETWORK_IOespera:

sqldk.dll!SOS_DispatcherBase::GetTrack+0x7f6c
sqldk.dll!SOS_Scheduler::PromotePendingTask+0x204
sqldk.dll!SOS_Task::PostWait+0x5f
sqldk.dll!SOS_Scheduler::Suspend+0xb15
sqllang.dll!CSECCNGProvider::GetBCryptHandleFromAlgID+0xf6af
sqllang.dll!CSECCNGProvider::GetBCryptHandleFromAlgID+0xf44c
sqllang.dll!SNIPacketRelease+0xd63
sqllang.dll!SNIPacketRelease+0x2097
sqllang.dll!SNIPacketRelease+0x1f99
sqllang.dll!SNIPacketRelease+0x18fe
sqllang.dll!CAutoExecuteAsContext::Restore+0x52d
sqllang.dll!CSQLSource::Execute+0x151b
sqllang.dll!CSQLSource::Execute+0xe13
sqllang.dll!CSQLSource::Execute+0x474
sqllang.dll!SNIPacketRelease+0x165d
sqllang.dll!CValOdsRow::CValOdsRow+0xa92
sqllang.dll!CValOdsRow::CValOdsRow+0x883
sqldk.dll!ClockHand::Statistic::RecordClockHandStats+0x15d
sqldk.dll!ClockHand::Statistic::RecordClockHandStats+0x638
sqldk.dll!ClockHand::Statistic::RecordClockHandStats+0x2ad
sqldk.dll!SystemThread::MakeMiniSOSThread+0xdf8
sqldk.dll!SystemThread::MakeMiniSOSThread+0xf00
sqldk.dll!SystemThread::MakeMiniSOSThread+0x667
sqldk.dll!SystemThread::MakeMiniSOSThread+0xbb9

Finalmente, notei que o SSMS usa uma quantidade surpreendente de CPU durante o loop (cerca de meio núcleo em média). Não consigo descobrir o que o SSMS está fazendo durante esse período.

Por que um loop simples causa ASYNC_NETWORK_IOesperas quando executado por meio do SSMS? A única saída que pareço obter do cliente dessa execução de consulta é "Comandos concluídos com êxito". mensagem.

sql-server ssms
  • 1 1 respostas
  • 2410 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2019-03-22T22:42:40+08:002019-03-22T22:42:40+08:00

    A documentação para SET NOCOUNTdiz:

    SET NOCOUNT ONimpede o envio de DONE_IN_PROCmensagens ao cliente para cada instrução em um procedimento armazenado. Para procedimentos armazenados que contêm várias instruções que não retornam muitos dados reais ou para procedimentos que contêm loops Transact-SQL, definir SET NOCOUNTcomo ONpode fornecer um aumento significativo de desempenho, pois o tráfego de rede é bastante reduzido.

    Você não está executando as instruções em um procedimento armazenado, portanto, o SQL Server envia DONEtokens (código 0xFD) para indicar o status de conclusão de cada instrução SQL. Essas mensagens são adiadas e enviadas de forma assíncrona quando o pacote de rede está cheio. Quando o cliente não consome pacotes de rede com rapidez suficiente, eventualmente os buffers ficam cheios e a operação torna-se bloqueante para o SQL Server, gerando as ASYNC_NETWORK_IOesperas.

    Observe que os DONEtokens são diferentes de DONEINPROC(code 0xFF) conforme a documentação observa:

    • Um DONEtoken é retornado para cada instrução SQL no lote SQL, exceto declarações de variáveis.

    • Para execução de instruções SQL em procedimentos armazenados, DONEPROCtokens DONEINPROCsão usados ​​no lugar de DONEtokens.

    Você verá uma redução drástica nas ASYNC_NETWORK_IOesperas usando:

    CREATE PROCEDURE #P AS
    SET NOCOUNT ON;
    
    DECLARE
        @outer_loop integer = 0,
        @big_string_for_u varchar(8000);
    
    
    WHILE @outer_loop < 5000000
    BEGIN
        SET @big_string_for_u = 'ZZZZZZZZZZ';
        SET @outer_loop = @outer_loop + 1;
    END;
    GO
    EXECUTE dbo.#P;
    

    Você também pode usar sys.sp_executesqlpara obter o mesmo resultado.

    Exemplo de rastreamento de pilha capturado assim que uma ASYNC_NETWORK_IOespera começa:

    enviando um pacote

    Um exemplo de pacote TDS visto na função inline sqllang!srv_completioncode_ex<1>tinha os seguintes 13 bytes:

    fd 01 00 c1 00 01 00 00 00 00 00 00 00          
    

    Que decodifica para:

    • Tipo de token = 0xfdDONE_TOKEN
    • Estado = 0x0001DONE_MORE
    • CurCmd = 0x00c1 (193)
    • DoneRowCount = 0x00000001 (1)

    Em última análise, o número de ASYNC_NETWORK_IOesperas depende do cliente e do driver e do que ele faz, se houver, com todas as DONEmensagens. Testando com um loop 1/10 do tamanho fornecido na pergunta (5.000.000 iterações de loop), descobri que o SSMS foi executado por cerca de 4 segundos com 200-300 ms de espera. sqlcmdfuncionou por 2-3 segundos com esperas de ms de um dígito; osqlem torno do mesmo tempo de execução com cerca de 10 ms de espera.

    O pior cliente para este teste foi o Azure Data Studio. Ele funcionou por quase 6 horas:

    PUBLICIDADES

    • 37

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve