Temos uma tarefa em execução todos os dias despejando os resultados de uma consulta em um arquivo CSV -- como o stdout da sqlplus
execução de uma consulta.
O número de registros é de muitos milhões (não pergunte), e o trabalho leva mais de duas horas.
Ao tentar melhorar os tempos, escrevi um programa C (usando a ofetch()
chamada do Oracle), mas o desempenho não mudou ... Aumentando o tamanho da Unidade de Dados da Sessão (SDU) (para 1 GB! no cliente - não tenho certeza , onde o servidor iria prendê-lo) não ajudou.
Em seguida, fiz mais algumas pesquisas e descobri que ofen()
, se usado para capturar várias linhas ao mesmo tempo, pode melhorar drasticamente o desempenho - e mudei meu programa C para usá-lo.
Buscando 4K linhas de cada vez, os tempos caíram para 21 minutos - um fator de redução de 10x - causando muito regozijo.
Antes de passarmos pelo problema de instalar meu novo executável em servidores de produção, talvez o estoque sqlplus
também possa fazer a mesma busca de várias linhas - se fornecido com as opções de linha de comando adequadas?
Pode? Estamos usando o Oracle-11, embora, se esse recurso estiver disponível na versão 12 do cliente, poderíamos atualizar o lado do cliente...
SET ARRAYSIZE tem um padrão de 15
"Define o número de linhas que o SQL*Plus buscará do banco de dados de uma só vez.
Os valores válidos são de 1 a 5.000. Um valor grande aumenta a eficiência de consultas e subconsultas que buscam muitas linhas, mas requerem mais memória. Valores acima de aproximadamente 100 fornecem pouco desempenho agregado. ARRAYSIZE não afeta os resultados das operações do SQL*Plus além de aumentar a eficiência."
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqpug/SET-system-variable-summary.html#GUID-773AEA4E-060E-4C1E-B1A0-52F7DE084AE8
Existem ajustes adicionais que podem ser feitos (incluindo o SDU) no sqlnet.ora (alterando o DEFAULT_SDU_SIZE ) ou na string de conexão. Isso pode ser definido em tnsnames.ora, mas você também pode colocá-lo como parte de uma string de conexão detalhada, como
Coloque seus valores apropriados para usr,pwd,svr e svc https://docs.oracle.com/cd/E18283_01/network.112/e10836/performance.htm
Acho que o conselho de Gary é bom. Você também pode tentar testar com utl_file ou um script Perl que grava os dados em um arquivo diretamente. Eu hesitaria em escrever um programa em C, pois isso exigirá um nível mais alto de experiência para manter.