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 / 123370
Accepted
Peter
Peter
Asked: 2015-12-11 02:37:28 +0800 CST2015-12-11 02:37:28 +0800 CST 2015-12-11 02:37:28 +0800 CST

Aplicativo consultando tabelas vazias

  • 772

Minha empresa usa um aplicativo que apresenta problemas de desempenho bastante importantes. Há uma série de problemas com o próprio banco de dados que estou trabalhando, mas muitos dos problemas são puramente relacionados ao aplicativo.

Em minha investigação, descobri que existem milhões de consultas no banco de dados do SQL Server que consultam tabelas vazias. Temos cerca de 300 tabelas vazias e algumas dessas tabelas são consultadas até 100-200 vezes por minuto. As tabelas não têm nada a ver com a nossa área de negócios e são essencialmente partes do aplicativo original que o fornecedor não removeu quando foi contratado pela minha empresa para produzir uma solução de software para nós.

Além do fato de suspeitarmos que nosso log de erros do aplicativo está sendo inundado com erros relacionados a esse problema, o fornecedor nos garante que não há impacto no desempenho ou na estabilidade do aplicativo ou do servidor de banco de dados. O log de erros é inundado na medida em que não podemos ver mais de 2 minutos de erros para fazer diagnósticos.

O custo real dessas consultas obviamente será baixo em termos de ciclos de CPU, etc. Mas alguém pode sugerir qual seria o efeito no SQL Server e no aplicativo? Eu suspeitaria que a própria mecânica de enviar uma solicitação, confirmá-la, processá-la, devolvê-la e confirmar o recebimento pelo aplicativo teria um impacto no desempenho.

Usamos SQL Server 2008 R2, Oracle Weblogic 11g para o aplicativo.

@Frisbee- Para encurtar a história, criei uma tabela contendo o querytext que atingiu as tabelas vazias no banco de dados do aplicativo e, em seguida, consultei todos os nomes de tabelas que sei que estão vazios e obtive uma lista muito longa. O maior sucesso foi de 2,7 milhões de execuções em 30 dias de tempo de atividade, tendo em mente que o aplicativo geralmente é usado das 8h às 18h, portanto esses números estão mais concentrados no horário operacional. Várias tabelas, várias consultas, provavelmente algumas relevantes por meio de junções, outras não. O maior sucesso (2,7 milhões na época) foi uma simples seleção de uma única tabela vazia com uma cláusula where, sem junções. Eu esperaria que consultas maiores com junções às tabelas vazias pudessem incluir atualizações para tabelas vinculadas, mas verificarei isso e atualizarei esta pergunta o mais rápido possível.

Atualização: Existem 1000 consultas com uma contagem de execução entre 1043 - 4622614 (mais de 2,5 meses). Terei que cavar mais para descobrir de onde o plano em cache se origina. Isso é apenas para lhe dar uma ideia da extensão das consultas. A maioria é razoavelmente complexa com mais de 20 junções.

@srutzky- sim, acredito que haja uma coluna de data relacionada a quando o plano foi compilado para que seja interessante, então vou verificar isso. Eu me pergunto se os limites de thread seriam um fator quando o SQL Server fica em um cluster VMware? Em breve será um Dell PE 730xD dedicado, felizmente.

@Frisbee - Desculpe pela resposta tardia. Como você sugeriu, executei um select * da tabela vazia 10.000 vezes em 24 threads usando SQLQueryStress (na verdade, 240.000 iterações) e atingi 10.000 solicitações de lote/s imediatamente. Em seguida, reduzi para 1.000 vezes em 24 threads e atingi pouco menos de 4.000 solicitações de lote/seg. Também tentei 10.000 iterações em apenas 12 threads (portanto, 120.000 iterações no total) e isso produziu 6.505 lotes/s sustentados. O efeito na CPU foi realmente perceptível, cerca de 5-10% do uso total da CPU durante cada execução de teste. As esperas de rede foram insignificantes (como 3 ms com o cliente em minha estação de trabalho), mas o impacto da CPU estava lá com certeza, o que é bastante conclusivo no que me diz respeito. Parece resumir-se ao uso da CPU e um pouco de arquivo de banco de dados desnecessário IO. O total de execuções/segundo chega a pouco menos de 3.000, o que é mais do que em produção, porém estou testando apenas uma das dezenas de consultas como esta. O efeito líquido de centenas de consultas atingindo tabelas vazias a uma taxa entre 300 e 4.000 vezes por minuto, portanto, não seria desprezível quando se trata de tempo de CPU. Todos os testes foram feitos em um PE 730xD inativo com dual flash array e 256 GB de RAM, 12 núcleos modernos. Esta é a saída do SQLSentry

@srutzky- bom pensamento. SQLQueryStress parece usar o pool de conexões por padrão, mas eu dei uma olhada de qualquer maneira e descobri que sim, a caixa para pool de conexões está marcada. Atualização a seguir

@srutzky- O pool de conexões aparentemente não está ativado no aplicativo - ou, se estiver, não está funcionando. Fiz um rastreamento do profiler e descobri que as conexões têm EventSubClass "1 - Nonpooled" para eventos de login de auditoria.

RE: Pool de conexão - verifiquei o weblogics e encontrei o pool de conexão ativado. Executei mais rastreamentos ao vivo e encontrei sinais de agrupamento que não estava ocorrendo corretamente/de forma alguma: insira a descrição da imagem aqui

E aqui está o que parece quando executo uma única consulta sem junções em uma tabela preenchida; as exceções diziam "Ocorreu um erro relacionado à rede ou específico da instância ao estabelecer uma conexão com o SQL Server. O servidor não foi encontrado ou não estava acessível. Verifique se o nome da instância está correto e se o SQL Server está configurado para permitir conexões remotas. (provedor: Provedor de pipes nomeados, erro: 40 - Não foi possível abrir uma conexão com o SQL Server)" Observe o contador de solicitações em lote. Fazer ping no servidor durante o tempo em que as exceções são geradas resulta em uma resposta de ping bem-sucedida.

insira a descrição da imagem aqui

Atualização - duas execuções de teste consecutivas, mesma carga de trabalho (selecione*fromEmptyTable), pool ativado/desativado. Um pouco mais de uso da CPU e muitas falhas e nunca ultrapassa 500 solicitações em lote/seg. Os testes mostram 10.000 lotes/s e nenhuma falha com o pool ativado, e cerca de 400 lotes/s e muitas falhas devido à desativação do pool. Será que essas falhas estão relacionadas a falta de disponibilidade de conexão?

insira a descrição da imagem aqui

@srutzky- Selecione Count(*) em sys.dm_exec_connections;

  • Pooling ativado: 37 de forma consistente, mesmo após o teste de carga parar

  • Pooling desabilitado: 11-37, dependendo se as exceções estão
    ocorrendo ou não no SQLQueryStress, ou seja: quando essas depressões aparecem no
    gráfico de Lotes/seg, as exceções ocorrem no SQLQueryStress e o
    número de conexões cai para 11, depois volta gradualmente para 37 quando os lotes começam a atingir o pico e as exceções não estão ocorrendo. Muito, muito interessante.

Conexões máximas em ambas as instâncias de teste/ativas definidas no padrão de 0.

Verifiquei os logs do aplicativo e não consegui encontrar problemas de conectividade, no entanto, há apenas alguns minutos de log disponíveis devido ao grande número e tamanho dos erros, ou seja: muitos erros de rastreamento de pilha. Um colega do suporte de aplicativos informa que ocorre um número substancial de erros de HTTP relacionados à conectividade. Com base nisso, parece que, por algum motivo, o aplicativo não está agrupando corretamente as conexões e, como resultado, o servidor está ficando sem conexões repetidamente. Vou examinar mais os logs do aplicativo. Gostaria de saber se existe uma maneira de provar que isso está acontecendo na produção do lado do SQL Server?

@srutzky- Obrigado. Vou verificar a configuração do weblogic amanhã e atualizar. Eu estava pensando nas meras 37 conexões - se SQLQueryStress está fazendo 12 threads em 10.000 iterações = 120.000 instruções select não agrupadas, isso não deveria significar que cada select cria uma conexão distinta com a instância sql?

@srutzky- Weblogics estão configurados para agrupar conexões, então deve estar funcionando bem. O pool de conexões é configurado assim, em cada um dos 4 weblogics com balanceamento de carga:

  • Capacidade Inicial: 10
  • Capacidade Máxima: 50
  • Capacidade Mínima: 5

Quando eu aumento o número de threads que executam a seleção da consulta de tabela vazia, o número de conexões atinge o pico em torno de 47. Com o pool de conexões desabilitado, vejo consistentemente um número máximo de solicitações de lote por segundo (de 10.000 para cerca de 400). O que acontecerá sempre é que as 'exceções' em SQLQueryStress ocorrem logo após os lotes/s entrarem em um vale. Está relacionado à conectividade, mas não consigo entender exatamente por que isso está acontecendo. Quando nenhum teste está sendo executado, #connections cai para cerca de 12.

Com o pool de conexões desativado, estou tendo problemas para entender por que as exceções ocorrem, mas talvez seja uma outra pergunta/pergunta stackExchange para Adam Machanic?

@srutzky Eu me pergunto então por que as exceções ocorrem sem o pooling ativado, mesmo que o SQL Server não esteja ficando sem conexões?

sql-server sql-server-2008-r2
  • 3 3 respostas
  • 612 Views

3 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-12-11T09:23:04+08:002015-12-11T09:23:04+08:00

    Eu suspeitaria que a própria mecânica de enviar uma solicitação, confirmá-la, processá-la, devolvê-la e confirmar o recebimento pelo aplicativo teria um impacto no desempenho.

    Sim, e existem até alguns fatores adicionais, mas o grau em que qualquer um deles está realmente afetando seu sistema é impossível dizer sem analisar o sistema.

    Dito isto, você está perguntando o que poderia ser um problema, e há algumas coisas a serem mencionadas, mesmo que algumas delas não sejam atualmente um fator em sua situação particular. Você diz que:

    Temos cerca de 300 tabelas vazias e algumas dessas tabelas são consultadas até 100-200 vezes por minuto.

    • Tabelas vazias que não estão sendo consultadas não são um problema. Mas acho que você também pode estar querendo dizer que todos estão sendo questionados, apenas que alguns estão sendo atingidos muito mais do que outros.
    • A análise da consulta e a geração do plano de execução não devem ser um grande problema se o texto da consulta que está sendo enviado permanecer o mesmo nas chamadas. O SQL Server fará o hash do texto da consulta e o procurará no cache do plano. Se encontrado, ele não executará as etapas de análise ou compilação novamente (até que o plano seja removido do cache).
    • Qualquer tabela, vazia ou não vazia, exigirá pelo menos um bloqueio "compartilhado" para indicar que o recurso está sendo usado. Isso evita que operações que exijam bloqueios exclusivos (adicionar/alterar/remover colunas, etc) façam a alteração enquanto o recurso estiver em uso. Bloquear e desbloquear, mesmo que seja realizado em menos de 1 milissegundo, pois não há dados, ainda requer recursos do sistema (memória e CPU) para gerenciar essas operações de bloqueio.
    • Mesmo sem nenhum conjunto de resultados voltando para o aplicativo do SQL Server, ainda há a mesma quantidade de tráfego de rede indo para o SQL Server, independentemente de a consulta gerar resultados ou não. O texto da consulta ou nome do procedimento armazenado precisa ser enviado. E mesmo que nenhum resultado volte, o SQL Server ainda precisa enviar alguns pacotes de rede contendo a estrutura do conjunto de resultados, além de pacotes informando ao cliente que um conjunto de resultados está iniciando (mesmo que nenhuma linha seja encontrada) e, em seguida, que o conjunto de resultados é terminando e deve ser fechado. E pode haver mensagens adicionais de instruções de impressão e/ou contagem de linhas.
    • Conectar-se ao SQL Server requer uma certa quantidade de recursos do sistema. É preciso CPU e memória para lidar com a autenticação (bem como pacotes de rede de ida e volta) e isso também leva tempo. É por isso que existe o Connection Pooling: para reduzir essa despesa.
    • Mesmo com o Connection Pooling reduzindo o uso de recursos do sistema, o SQL Server ainda precisa manter essas conexões e isso requer memória e um mínimo de CPU.
    • Mesmo sem linhas e, portanto, com um tempo de execução muito rápido, a consulta ainda foi executada. Mesmo que houvesse 10 ou 10.000 linhas e elas fossem extraídas do Buffer Pool (ou seja, memória), pois eram usadas com frequência, um thread ainda precisa fazer esse trabalho. E um thread que está trabalhando nessa consulta inútil não está funcionando em uma consulta útil real.

    Pode até haver mais, mas isso deve ajudar a ter uma noção das coisas. E lembre-se de que, como a maioria dos problemas de desempenho, tudo é uma questão de escala. Todos os itens mencionados acima não são problemas se forem atingidos uma vez por minuto. É como testar uma alteração em sua estação de trabalho ou no banco de dados de desenvolvimento: sempre funciona com apenas 10 a 100 linhas nas tabelas. Mova esse código para produção e leva 10 minutos para ser executado, e alguém certamente dirá: "bem, funciona na minha caixa" ;-). Ou seja, é apenas devido ao grande volume de chamadas feitas que você está vendo um problema, mas essa é a situação que existe.

    Portanto, mesmo com 1 milhão de consultas de linha inúteis e 0, isso equivale a:

    • um extra de 2 milhões de operações de bloqueio (todo bloqueio deve ser desbloqueado, certo?). isso é principalmente um custo de tempo gasto em uma operação inútil em vez de uma operação útil.
    • mais tráfego de rede que pode estar aproximando você da saturação (não tenho certeza da probabilidade disso, mas ainda assim)
    • mais conexões sendo mantidas que ocupam mais memória. Quanta RAM física não utilizada você tem? essa memória seria melhor usada para executar consultas e/ou cache do plano de consulta. Na pior das hipóteses, você está sem memória física e o SQL Server precisa começar a usar a memória virtual (swap), pois isso torna as coisas mais lentas (verifique o log de erros do SQL Server para ver se você está recebendo mensagens sobre a memória sendo paginada).

      E apenas no caso de alguém mencionar, "bem, há um pool de conexões". Sim, isso definitivamente ajuda a reduzir o número de conexões necessárias. Mas com consultas chegando até 200 vezes por minuto, isso é muita atividade simultânea e conexões ainda precisam existir para as solicitações legítimas. Faça um SELECT * FROM sys.dm_exec_connections;para ver quantas conexões ativas você está mantendo.

    • independentemente de qualquer outra coisa, ainda é pelo menos 1 milhão de vezes durante cada dia que um thread que poderia estar fazendo algo útil estava indisponível.

    Se não estou errado sobre o que venho afirmando aqui, então me parece que, mesmo que em pequena escala, este é um tipo de ataque DDoS ao seu sistema, pois está inundando a rede e seu SQL Server com solicitações falsas , evitando que solicitações reais cheguem ao SQL Server ou sejam processadas pelo SQL Server.

    • 7
  2. paparazzo
    2015-12-11T11:04:21+08:002015-12-11T11:04:21+08:00

    Se as tabelas estão sendo atingidas 100-200 vezes por minuto, então elas estão (espero) na memória. A carga no servidor é muito, muito baixa. A menos que você tenha alta CPU ou memória no servidor de banco de dados, isso provavelmente não é um problema.

    Sim, as consultas aceitam bloqueios compartilhados, mas esperamos que não estejam bloqueando nenhum bloqueio de atualização nem sendo bloqueadas por nenhum bloqueio de atualização. Você tem alguma atualização, inserção ou exclusão nessas tabelas. Caso contrário, eu simplesmente deixaria para lá - se você está tendo problemas de desempenho, deve haver peixes maiores para fritar do ponto de vista do servidor de banco de dados.

    Fiz um teste em 100.000 select count(*) em uma tabela vazia e ele foi executado em 32 segundos e as consultas foram feitas em uma rede. Então 1/3 milissegundo. A menos que sua rede esteja ficando sobrecarregada, isso nem afeta o cliente. Se você estiver tendo grandes problemas de desempenho, essas consultas em branco de 1/3 milissegundos não são o que está matando o aplicativo.

    E isso pode ser apenas parte de uma junção à esquerda, capturando alguns dados do tipo estático que não fazem parte do aplicativo atual. Ele pode ser encadeado com outras consultas, portanto, não é uma ida e volta extra. Se sim, é desleixado, mas nem está causando mais tráfego.

    Então, voltemos a olhar para as declarações reais. Você está vendo alguma atualização, adição ou exclusão nessas tabelas?

    Sim, muitas tabelas vazias e consultas a tabelas vazias são indicação de codificação desleixada. Mas se você está tendo grandes problemas de desempenho, esta não é a causa, a menos que você tenha algumas operações de gravação realmente desleixadas também acontecendo com essas tabelas.

    • 1
  3. alonk
    2015-12-11T05:55:18+08:002015-12-11T05:55:18+08:00

    Em geral, em cada consulta, as seguintes etapas são realizadas:

    1. Solicitação do Aplicativo.
    2. Banco de dados Analise a consulta.
    3. O mecanismo de banco de dados verifica se esta consulta já está armazenada na RAM. use o plano de execução se existir na memória.
    4. se não existir na RAM, o mecanismo de banco de dados verifica as estatísticas existentes nos objetos na consulta e determina o plano de execução.
    5. Execute o plano de execução, use i/o para obter dados do disco.
    6. resposta ao aplicativo.

    muitas consultas como você mencionou podem causar carga extra em um sistema que já é pesado - carga extra em conexões, CPU, RAM e E/S.

    • 0

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