Instrução SELECT remota lenta devido ao longo "tempo de processamento do cliente", mas rápido localmente

12

Enquanto conectada ao nosso servidor de produção (SQL Server 2008, máquina muito poderosa), essa instrução SELECT leva 2 segundos , retornando todos os campos (4 MB de dados no total).

SELECT TOP (30000) *
FROM person
WITH(NOLOCK);

De qualquer outra caixa na mesma rede (conexão usando autenticação SQL ou autenticação do Windows), a mesma consulta leva 1 minuto, 8 segundos .

Estou testando com esta declaração muito simples para ilustrar que não é um problema de indexação ou relacionado a consultas. (Temos problemas de desempenho com todas as consultas no momento ...)

As linhas vêm em pedaços, e nem todos de uma vez. Recebo minhas primeiras linhas instantaneamente e espero mais de um minuto para que os lotes de linhas entrem.

Aqui estão as estatísticas do cliente da consulta, quando é executada a partir da caixa remota:

Query Profile Statistics
  Number of INSERT, DELETE and UPDATE statements 0
  Rows affected by INSERT, DELETE, or UPDATE statements 0
  Number of SELECT statements  2
  Rows returned by SELECT statements 30001
  Number of transactions 0

Network Statistics
  Number of server roundtrips 3
  TDS packets sent from client        3
  TDS packets received from server 1216
  Bytes sent from client         266
  Bytes received from server 4019800

Time Statistics
  Client processing time 72441 ms (72 seconds)
  Total execution time   72441 ms
  Wait time on server replies 0

Podemos ver que o "Tempo de processamento do cliente" é igual ao tempo total de execução.

Alguém sabe quais etapas eu posso executar para diagnosticar por que a transferência dos dados reais está demorando muito?

Existe um parâmetro de configuração SQL que restrinja ou limite a velocidade de transferência de dados entre máquinas?

FranticRock
fonte
A propósito, tentamos copiar o arquivo do mesmo tamanho (4 MB) entre o servidor DB e outra caixa, e isso levou um segundo. Portanto, não parece ser um problema de rede.
FranticRock
O que é o aplicativo cliente? SSMS nas estações de trabalho do usuário final?
Thomas Stringer
Sim Microsoft SQL Server Management Studio 10.50.1600.1. 2008 R2
FranticRock
Esse problema começou desde que movemos os datacenters e a máquina inteira foi reinstalada (tudo incluindo SQL). Estamos com um provedor de hospedagem muito respeitável.
FranticRock

Respostas:

5

Seu problema é definitivamente relacionado à rede, com base em suas informações. Como tal, tem que ser tratado com profissionais da rede (não sou eu).

Coisas que podem ajudar:

  • Placas NIC mais rápidas (no servidor SQL).
  • Adição de placa / sub-rede NIC específica / alocada entre os servidores (servidor Web e SQL Server).

O servidor da web está na mesma sub-rede que o servidor SQL?

Existem roteadores / pontes etc. entre eles?

Não há muitas alterações possíveis no servidor SQL:

  • Os dados de saída estão sendo enviados pelo SQL Server com o MS "protocolo TDS" proprietário.
  • O tamanho padrão do buffer TDS é de 4 KB. Consulte no MSDB: "opção de tamanho de pacote de rede"
  • A compactação dos dados (com o SQL Server ou um aplicativo externo) - depende da natureza dos dados.

Você está usando um tamanho padrão: consulte suas estatísticas: "Pacotes TDS recebidos do servidor 1216" (4MB / 1K = 4KB). Sim, o tamanho do buffer TDS pode ser alterado: consulte no google: "Tamanho do lote do protocolo TDS"

Boa discussão sobre o tópico: "o tamanho do pacote de rede do sql realmente determina o tráfego de ida e volta?"

No entanto, alterar o tamanho do pacote TDS (inevitavelmente) terá efeitos imprevisíveis e só deve ser usado na produção em casos excepcionais.

A alteração da arquitetura ou a introdução do armazenamento em cache de dados na camada intermediária também ajudaria.

alexei
fonte
8

Este problema está agora resolvido.

Era um problema de rede e a caixa SQL estava usando uma placa NIC de 100 MB / s em vez de uma placa NIC de 10 GB / s ...

Uma alteração na configuração da rede para usar a placa de rede correta corrigiu o problema. Agora estamos obtendo desempenho semelhante para todas as consultas da caixa SQL de produção e de outras caixas na rede.

Obrigado a todos por sua ajuda.

FranticRock
fonte
Eu tenho exatamente o mesmo problema que você e quero verificar qual placa de NIC meu SQL Server usa. Onde eu posso ver isso?
Misha Zaslavsky
3

Na leitura inicial, parece que você está enfrentando alguns problemas de latência da rede. Você já viu alguns dos contadores do Network Perfmon? Isso pode lhe dar alguma indicação do que está acontecendo com a rede.

Citação de Quais balcões de Perfmon devo monitorar e o que cada um deles significa?

REDE IO

Para medir a E / S de rede, você pode usar os seguintes contadores:

Interface de redeBytes Total / s

Limite: valores sustentados de mais de 80% da largura de banda da rede.

Significado: Este contador indica a taxa na qual os bytes são enviados e recebidos por cada adaptador de rede. Esse contador ajuda você a saber se o tráfego no seu adaptador de rede está saturado e se você precisa adicionar outro adaptador de rede. A rapidez com que você pode identificar um problema depende do tipo de rede que você possui e se compartilha a largura de banda com outros aplicativos.

Interface de redeBytes recebidos / s

Este contador indica a taxa na qual os bytes são recebidos em cada adaptador de rede. Você pode calcular a taxa de dados recebidos como parte da largura de banda total. Isso ajudará você a saber que você precisa otimizar os dados recebidos do cliente ou que você precisa adicionar outro adaptador de rede para lidar com o tráfego recebido.

Interface de redeBytes enviados / s

Este contador indica a taxa na qual os bytes são enviados por cada adaptador de rede. Você pode calcular a taxa de dados recebidos como parte da largura de banda total. Isso o ajudará a saber que você precisa otimizar os dados que estão sendo enviados para o cliente ou precisa adicionar outro adaptador de rede para lidar com o tráfego de saída.

ServerBytes Total / s

Esse valor não deve exceder 50% da capacidade da rede.

Este contador indica o número de bytes enviados e recebidos pela rede. Valores mais altos indicam a largura de banda da rede como o gargalo. Se a soma do total de bytes / s para todos os servidores for aproximadamente igual às taxas máximas de transferência da sua rede, pode ser necessário segmentar a rede.

% De tempo de interrupção do processador

Esse contador indica a porcentagem de tempo que o processador gasta para receber e reparar o hardware interrompe. Esse valor é um indicador indireto da atividade de dispositivos que geram interrupções, como adaptadores de rede.

Comprimento da fila de saída da interface de rede (*)

Este contador verifica quantos segmentos estão aguardando no adaptador de rede. Se houver muitos encadeamentos aguardando no adaptador de rede, o sistema provavelmente saturará a E / S da rede, provavelmente devido à latência ou largura de banda da rede.

Comprimento da fila de saída é o comprimento da fila de pacotes de saída (em pacotes). Se isso for maior que dois, haverá atrasos e o gargalo deverá ser encontrado e eliminado, se possível. Como as solicitações são enfileiradas pelo NDIS (Network Driver Interface Specification) nesta implementação, sempre será 0.

jgardner04
fonte
Depois de monitorar essas estatísticas no Perfmon, notei algumas coisas. O total de bytes / s nunca sobe mais de 700 K / s em nenhuma das placas de rede. Mesmo se eu estiver executando uma consulta que solicita megabytes de dados, esse número permanece em torno de 500K / s. Nossa largura de banda é de 100 MBPS e nem chegamos a 1% de uso. Eu estou pensando que deveria haver um limite configurado em algum lugar que está forçando o tamanho dos pacotes ou limitando a taxa de transferência. As interrupções de hardware / s estão entre 700 e 2000. A fila de saída está vazia. O uso da placa de rede atinge o pico mais alto em cerca de 4%.
FranticRock
2
Pode haver uma incompatibilidade entre a velocidade da placa de rede e a porta do switch. Você contratou sua equipe de rede para analisá-la do lado do switch?
Jgardner04
2

Algumas perguntas preliminares: 1) O servidor possui um cliente SQL no Prod. configuração da máquina do servidor, certo? Então, se você fizer a mesma consulta do cliente localizado na mesma máquina, ela será concluída em 2 segundos? Você tentou fazer isso? São realmente 2 segundos? 2) Você mencionou que a configuração do seu ambiente de produção foi alterada (ou o servidor de produção foi movido para outra rede / reconstrução total do servidor), certo? Qual foi o tempo de consumo da consulta no antigo ambiente de produção?

De qualquer outra caixa na mesma rede ... a mesma consulta leva 1 minuto, 8 segundos. 3) Você está dizendo que a consulta retorna e é consumida pelo cliente, localizada em qualquer máquina da rede em questão (exceto sua máquina específica) em cerca de 70 segundos? Eu entendi corretamente? 3.1 Aliás, qual é o momento para o consumo dessa consulta, aceitável pelos negócios? 4) No entanto, você está especificando que, para uma máquina cliente específica que você está usando, o tempo de consumo da saída da consulta é: Tempo de Execução do Cliente 15:30: 48 15 minutos? (e desta vez claramente não é aceitável)? Corrigir? 5) então o problema está limitado a uma única máquina cliente? Ou para QUALQUER cliente / máquina de camada intermediária etc. (em um novo ambiente)? 6) qual é o atraso mostrado pelo ping? do computador cliente para o servidor? 7) Você (ou administrador da rede) executou o tracert nos dois sentidos (do cliente para o servidor, do servidor para o cliente)? Quantos saltos? Qual é o tempo combinado? 8) A antiga rede de produção está viva? Você pode comparar usando Ping e Traceroute - qual foi o tempo e o salto entre o cliente e o servidor lá?

Por curiosidade: este é um exemplo da consulta? ou redação exata da consulta? A consulta NÃO contém realmente a cláusula WHERE? Concordo comigo que isso é muito incomum .. A tabela possui um índice em cluster ou é um Heap? A tabela contém quantas linhas no total? A tabela está muito fragmentada? Por curiosidade: por que SELECT TOP NNN? Por que não SET ROWCOUNT NNN - depois SELECT *? Esta consulta é emitida quantas vezes pelo cliente por dia? 1? 100? 1MLN? Os dados subjacentes são estáticos ou dinâmicos e são muito alterados? Quanto (0,01% ao dia? 1% ao dia? 10% ao dia?) A saída da consulta é processada programaticamente? (não por um usuário?) Por que não é armazenado em cache / não é armazenado na camada intermediária? obrigado Alexei

alexei
fonte
Muito obrigado pela informação. Minhas respostas abaixo. 1. Correto. As ferramentas cliente também instalaram no prod, e a mesma consulta mencionada leva 2 segundos para retornar todos os 30.000 registros (totalizando 4 MB de tamanho). A propósito, a consulta que usei é apenas um exemplo. Não é uma consulta comercial real. É apenas um meio de obter 4 MB de dados de uma tabela. Atualmente, temos um problema de desempenho ao ler vários megabytes de dados de qualquer tabela com qualquer consulta atualmente.
FranticRock
2. O tempo de consumo foi próximo, se não o mesmo da mesma consulta executada localmente na caixa PROD. (IE 2 segundos) 3. Isso mesmo 1 min 8 segundos é o tempo de execução. Esse tempo varia entre as diferentes máquinas clientes. Na nossa máquina de desenvolvimento (localizada muito mais longe que a máquina de palco), eu executei essa consulta 8 vezes seguidas, e o tempo variou de 11 segundos a 22 segundos. (média 18 seg.)
FranticRock
do nosso dev box tracert Prod_IP_Address 1 53 ms 52 ms 53 ms SQL2008 Na máquina de palco, o tempo é consistentemente superior a 1 minuto. tracert Prod_IP_Address tracert: 1 1 ms <1 ms <1 ms SQL2008 No servidor da web de produção: o tempo de execução é de 53 segundos. tracert: 1 1 ms <1 ms <1 ms SQL2008
FranticRock 1/12/12
4. A coluna superior "Horário de Execução do Cliente" é apenas o horário local da máquina (IE: 15:30:00) 5. O problema ocorre em qualquer máquina que atinge o servidor do DB de produção, inclusive no servidor da Web de produção. 6. O atraso do ping é <1 MS da caixa do estágio para a caixa SQL do prod. 7. Por favor, veja acima. 8. Infelizmente, a rede antiga não existe mais.
FranticRock
É realmente interessante que, embora o DEV faça ping em 53 MS, leva apenas 11 a 22 segundos para executar a consulta. Enquanto o estágio atinge 1 MS, leva mais de 1 minuto para retornar os dados. Dev também está muito mais longe geograficamente. E o palco está logo ao lado da caixa de produtos, e ainda está demorando muito mais.
FranticRock