Por que a consulta da Oracle na rede demoraria mais de 300 vezes, desde que fosse executada no servidor?

2

Recentemente, escrevi uma instrução SELECT complexa (baseada em muitos modos de exibição muito complexos) que levaria 1 hora e 50 minutos para ser executada quando executada a partir do Toad na minha área de trabalho e apenas alguns minutos mais rápido quando executada em um script Python. usando a biblioteca cx_Oracle (escrita para liberar para o disco a cada 50 linhas). O tamanho total do único conjunto de resultados foi de cerca de 8000 linhas, totalizando 5 MB. Durante a execução, minha estação de trabalho não estava se debatendo e a carga da CPU estava razoavelmente baixa.

A mesma consulta executada no servidor levou 21 segundos surpreendentes para produzir um conjunto idêntico de resultados byte a byte. Isso também foi gerado pelo mesmo script Python / cx_Oracle.

Transferir o arquivo do conjunto de resultados de 5 MB do servidor para minha estação de trabalho levou apenas 3 segundos, portanto, não acredito que a largura de banda da rede seja o problema direto.

O SQL * Net ou uma de suas bibliotecas associadas pode ser o culpado? Existem alguns problemas de gerenciamento de memória não linear quando as consultas são chamadas pela rede? Um conjunto de resultados de 5MB é grande, mas não é gigantesco nos dias de hoje. Há talvez algumas configurações de tamanho de buffer que ajudem? Estou usando uma instalação do cliente Oracle vanilla.

A estação de trabalho é o Windows XP Pro SP3 (somente 1 GB de RAM) com o cliente Oracle 10g e o Toad for Oracle Xpert 9.7.2.5 e o Python 2.6.2 com cx_Oracle 5.0.2. O servidor é o Red Hat 2.6.9-67.ELsmp em um servidor quad 8e Xeon 3.8GHz, executando o Oracle 10.2.0.4, o Python 2.3.4, cx_Oracle 4.4.1.

Editar: Opa! O arquivo tinha apenas 5 megabytes , não GB. Sinto muito.

Resolvido: houve um script de preenchimento que foi executado antes da consulta de extração que mencionei. Depois que esse script de preenchimento foi executado novamente, a consulta de extração demorou 2 horas para ser executada, independentemente da localização do programa cliente. Depois dessa primeira longa corrida, o conjunto de resultados deve ter sido armazenado em algum lugar, e eu não notei esse efeito até que metodicamente passei por todas as combinações.

    
por yukondude 30.05.2009 / 00:42

6 respostas

1

Dois pontos a ter em conta:

  • Você executou a consulta primeiro no Toad e depois em python + cx_Oracle? A primeira vez que você executa a consulta, o Oracle precisa analisar a consulta, criar um plano de execução e executar o plano: ler do disco na memória (cache de buffer), executar as junções, etc ... Na segunda vez, o Oracle usa o mesmo plano de execução (armazenado na SGA) e lê a partir do cache de buffer, não do disco. Pode ser muito menos tempo na segunda vez que você executar a mesma consulta.

  • Carregar 8000 linhas / 5GB de dados (655Kbytes por linha !!!) em TOAD, para exibi-los na GUI, pode levar muito tempo. Com python + cx_Oracle você não está exibindo nada, então está economizando muito tempo aqui.

EDITADO : OK, então 8000 linhas / 5 Mb de dados (655 bytes por linha) não devem ser um problema para o TOAD exibir.

  • Compare as variáveis de ambiente do Oracle no Linux com as variáveis de registro HKEY_LOCAL_MACHINE \ Software \ Oracle no Windows. Verifique se as variáveis NLS_SORT, NLS_LANG, NLS _... possuem o mesmo valor.
por 30.05.2009 / 12:57
2

Rastreie a execução no oracle e provavelmente você verá sua estação de trabalho buscando pequenos trechos de dados e adicionando latência rapidamente.

A solução pode ser buscar resultados em massa, como aqui:

Resolvendo a contenção do Oracle no TOAD; olhe no toadworld, procure por

http://www.toadworld.com/Experts/GuyHarrisonsImprovingOraclePerformance/ResolvingOracleContention/May2008OracleNetworkContention/tabid/374/Default.aspx

(desculpe, não é possível adicionar hiperlinks)

    
por 30.05.2009 / 06:22
1

Eu não conheço bem o Oracle em particular, mas a experiência anterior com os protocolos de rede para outros bancos de dados me disse que eles ignoram totalmente os problemas de latência. Em outras palavras, mesmo que não exista um montante de dados muito grande para transferir, as coisas ainda podem se tornar glaciais se você tiver que fazer várias viagens de ida e volta ao servidor para cada valor.

Você poderia testar essa teoria se adicionasse um pouco de latência à sua rede (sei que isso é possível no Linux, só posso imaginar que há uma maneira de fazê-lo no Windows) e ver se afeta significativamente o tempo de execução geral.

Outra opção é que parte do processamento pode estar sendo feito no lado do cliente, o que poderia estar transferindo muito mais do que 5 GB de dados intermediários para obter o resultado. Isso provavelmente apareceria como uma quantidade bastante significativa de carga na sua área de trabalho, por isso não é tão provável.

    
por 30.05.2009 / 01:40
1

Todos os sinais parecem apontar para um gargalo na rede. Que tipo de rendimento você recebe com transferências de arquivos entre esses dois computadores? Você pode tentar executar a mesma consulta em outro computador, mas mais perto na topologia da rede?

A taxa de transferência efetiva é de 6,2 Mbps - não é nada boa. Isso é um tiro no escuro, mas ... você está deixando de nos dizer que existe um modem a cabo entre sua estação de trabalho e o servidor? :)

Talvez sua estação de trabalho esteja conectada a um telefone IP e você esteja realmente conectado a 10 Mbps?

Desculpe se estou afirmando o óbvio, mas você não mencionou sua configuração de rede em sua pergunta.

    
por 30.05.2009 / 01:43
1

Uma declaração SELECT deve ser enviada integralmente ao servidor para análise e execução. Cabe ao cliente gerenciar como esses resultados são retornados. Eu apostaria muito que o problema está em como os resultados estão sendo obtidos por seus clientes. Já faz um tempo desde que eu usei o TOAD, então eu não sei se ele está fazendo buscas em lote dos dados, mas esse é um lugar onde você pode obter grandes melhorias na velocidade, como observa o @slovon.

Apenas para sorrisos, veja o que traceroute relata de sua estação de trabalho para o servidor e vice-versa.

EDIT: outra coisa para tentar é executar o script python no servidor, mas passar por uma conexão TNS através do ouvinte no servidor. Isso deve lhe dar uma ideia de qual efeito o software do TNS está tendo em sua consulta, ao mesmo tempo em que remove quaisquer problemas de rede intervenientes.

Além disso, verifique se o DNS está íntegro (precisa fazer pesquisas reversas) e se não está usando o DHCP no servidor. Sublinhados no nome do host também são um não-não.

    
por 30.05.2009 / 21:50
0

Obtenha um rastreamento com o tempo de espera nas sessões, tanto do TOAD quanto localmente. Em seguida, compare os eventos e tempos de espera, além do plano de execução. É possível que o plano seja diferente.

    
por 31.05.2009 / 03:09