Pergunta

Estou executando consultas contra um Oracle 10G com o JDBC (usando os drivers mais recentes e UCP como DataSource) para recuperar as clobs (Avg. 20K caracteres). No entanto, o desempenho parece ser muito ruim: a recuperação do lote de 100 lobs leva 4s em média. A operação também não é de E/S nem CPU, nem a rede, julgando minhas observações.

Minha configuração de teste é assim:

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

Eu experimentei os tamanhos de busca, mas sem sucesso. Estou fazendo algo errado? Existe uma maneira de acelerar a recuperação do CLOB ao usar o JDBC?

Foi útil?

Solução 4

Obrigado por todas as sugestões úteis. Apesar de ser sinalizado como resposta para o problema, minha resposta é que parece não haver uma boa solução. Tentei usar instruções paralelas, diferentes características de armazenamento, temperatura presortada. mesas e outras coisas. A operação parece não estar vinculada a qualquer característica visível através de traços ou explica planos. Mesmo o paralelismo da consulta parece ser superficial quando as falhas estão envolvidas.

Sem dúvida, haveria melhores opções para lidar com grandes clobs (especialmente compressão) em um ambiente de 11g, mas caixa eletrônico. Estou preso com 10g.

Eu optei agora por uma ida e volta adicional para o banco de dados, no qual pré -processarei os CLOBs em um brilho binário otimizado de tamanho otimizado. Nas implantações anteriores, isso sempre foi uma opção muito rápida e provavelmente valerá a pena manter um cache calculado offline. O cache será invalido e atualizará usando um processo persistente e aq até que alguém tenha uma idéia melhor.

Outras dicas

Minha experiência passada de usar dados do tipo Oracle Lob para armazenar dados grandes não foi boa. É bom quando fica abaixo de 4K, pois o armazena localmente como o VARCHAR2. Quando está acima de 4K, você começa a ver o desempenho degradado. Talvez as coisas possam ter melhorado desde a última vez que tentei alguns anos atrás, mas aqui estão as coisas que encontrei no passado para suas informações:

Como os clientes precisam obter o LOBS via Oracle Server, você pode considerar a seguinte situação interessante.

  • Os dados do LOB competirão cache SGA limitada com outro tipo de dados se o Oracle decidir cache. Como os dados da CLOB são gerais grandes, pode pressionar outros dados
  • Os dados do LOB obtêm uma leitura de disco ruim se o Oracle decidir não cache e transmitir os dados para o cliente.
  • A fragmentação provavelmente é algo que você ainda não encontrou. Você verá se seus aplicativos excluem lobs e o Oracle tenta reutilizar o LOB. Não sei se o Oracle suporta o desfragmentação on -line do disco para o LOB (eles têm para índices, mas leva muito tempo quando tentamos antes).

Você mencionou 4s para 100 lobs de AVG 20k, por isso são 40ms por lobs. Lembre -se de que cada LOB precisa precisar recuperar por localizador de LOB separado (não está no conjunto de resultados por padrão). Essa é uma viagem de ida e volta adicional para cada LOB, presumo (não tenho 100% de certeza disso, pois foi atrás) se for esse o caso, presumo que isso seja pelo menos 5ms de tempo extra por viagem de ida e volta em ordem em série , certo? Nesse caso, seu desempenho já está limitado pela primeira vez por busca sequencial de lobs. Você deve verificar isso rastreando o tempo gasto na execução do SQL versus busca de conteúdo do LOB. Ou você pode verificar isso excluindo a coluna LOB, conforme sugerido pela resposta anterior na postagem, o que deve dizer se está relacionado ao LOB.

Boa sorte

O tamanho total do conjunto de resultados está nos dez milhares - medido ao longo de toda a recuperação dos custos iniciais

Existe uma ordem na consulta? O 10K linhas é muito, se tiver que ser classificado.

Além disso, recuperar o PK não é um teste justo e recuperar todo o CLOB. O Oracle armazena as linhas de tabela com provavelmente muitas em um bloco, mas cada um dos clobs (se for> 4K) será armazenado fora da linha, cada um em uma série de blocos. A digitalização da lista de PKs será rápida. Além disso, provavelmente existe um índice no PK, para que o Oracle possa digitalizar rapidamente os blocos de índice e nem acessar a tabela.

4 segundos parecem um pouco altos, mas são 2 MB que precisam ser possíveis lidos no disco e transportados pela rede para o seu programa Java. A rede pode ser um problema. Se você executar um rastreamento SQL da sessão, ele apontará exatamente onde o tempo está sendo gasto (leituras de disco ou rede).

Eu tive um problema semelhante e encontrei o JDBC Lobs fazendo uma chamada de rede ao acessar as lobs.

A partir do driver Oracle 11.2G JDBC, você pode usar uma pré -busca. Isso acelerou o acesso por 10 vezes ...

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top