Estou implementando o recurso de importação de dados específicos do aplicativo de um banco de dados para outro.
Eu tenho um arquivo CSV contendo, digamos, 10000 linhas. Essas linhas precisam ser inseridas / atualizadas no banco de dados.
Pode ser o caso, em que algumas linhas podem aparecer no banco de dados, o que significa que essas precisam ser atualizadas. Se não estiver presente no banco de dados, eles precisam ser inseridos.
Uma solução possível é que eu posso ler uma por uma linha, verificar a entrada no banco de dados e criar consultas de inserção / atualização de acordo. Mas esse processo pode levar muito tempo para criar consultas de atualização / inserção e executá-las no banco de dados. Algumas vezes meu arquivo CSV pode ter milhões de registros.
Existe alguma outra maneira mais rápida de conseguir esse recurso?
OutOfMemory
!Respostas:
Existe uma boa tecnologia disponível no Oracle chamada External Tables. No seu cenário, você pode acessar seus dados externos em texto sem formatação usando Tabelas Externas de dentro do banco de dados e atualizar seus dados existentes no banco de dados com instruções SQL que você ama e que está acostumado - por exemplo
INSERT
,MERGE
etc.Na maioria dos casos, o uso de utilitários fornecidos pela Oracle é a melhor maneira de executar ETL. E como sua pergunta parece mais administrativa, sugiro que você analise minha postagem anterior no DBA Stack Exchange "Atualizar banco de dados Oracle de CSV" .
ATUALIZAÇÃO: Essa abordagem funciona muito bem para a leitura de dados externos no banco de dados. Geralmente, você define o formato de dados externos toda vez que precisar processar o arquivo de texto sem formatação que possui um novo formato. Depois que a tabela externa é criada, você pode consultá-la como uma tabela de banco de dados real. Sempre que houver novos dados para importar, basta substituir o (s) arquivo (s) subjacente (s) em tempo real, sem a necessidade de recriar tabelas externas. Como a tabela externa pode ser consultada como qualquer outra tabela do banco de dados, você pode escrever instruções SQL para preencher outras tabelas do banco de dados.
A sobrecarga do uso de tabelas externas geralmente é menor em comparação com outras técnicas que você implementaria manualmente, porque essa tecnologia foi projetada com o desempenho em mente, levando em consideração a arquitetura do banco de dados Oracle.
fonte
Eu acho que você deve usar o SQL * Loader para carregar o arquivo CSV na tabela temporária e, em seguida, use a instrução MERGE para inserir dados na tabela de trabalho.
O SQL * Loader lhe dará mais flexibilidade do que as tabelas externas e, se alguém usar o carregamento direto do caminho, será muito rápido. E o MERGE fará exatamente o que você precisa - INSERIR novos registros e ATUALIZAR os existentes.
Alguns links para iniciar:
http://docs.oracle.com/cd/B19306_01/server.102/b14215/ldr_concepts.htm
http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016 .htm
fonte
PreparedStatements tornará a criação de consultas de inserção ou atualização muito rápida. Você deve ter três
PreparedStatements
: um para inserção, um para atualização e outro para verificar se a linha já está na tabela. Se você conseguir manter os IDs iguais entre o arquivo CSV e o novo banco de dados, verificar se uma linha está presente usando o campo primaryID também deve ser muito rápido.O uso de uma inserção em lote pode oferecer um ganho de desempenho. À medida que você transmite o arquivo CSV, você verifica se a linha já está lá e então faz uma atualização ou adiciona a linha ao comando de inserção em lote. Você deve verificar esta questão do SO para comparar a velocidade dessas duas abordagens.
Se essa importação de banco de dados é algo que precisa ser feito regularmente e o desempenho é um problema usando o método descrito acima, você pode tentar manipular a tarefa com vários segmentos de trabalho. Use quantos threads forem processadores na máquina executando esse código.
Cada encadeamento obtém sua própria conexão com o banco de dados e, à medida que o código percorre o arquivo, as linhas do CSV podem ser transferidas para os diversos encadeamentos. Isso é muito mais complicado, então eu faria isso apenas se os requisitos de desempenho me obrigassem.
fonte