Problema com performance de banco de dados

Boa tarde pessoal,

Esta acontecendo a seguinte situação, tenho um banco de dados o qual possui uma coluna unica(UNIQUE). De ciclo em ciclo o sistema lê uma pasta de arquivos enorme para checar a existência de novos, quando encontra arquivo novo, este é analisado e tem suas informações inseridas no banco.

Ou seja, o sistema lê uma pasta, pega os arquivos novos e coloca as informações deste no banco.

O problema é a questão de performance, se eu deixo ele tentar colocar direto no banco, o banco retorna a Exception de chave unica duplicada e não insere os arquivos velhos (O que esta correto, e de certa forma é invisível pra quem usa o sistema, uma vez que as Exceptions nao param a execução da tarefa), entretanto estou querendo otimizar este processo, a minha idéia foi:

Ler a coluna unica do banco e colecionar ela, e a cada tentativa de inserção checar primeiro nesta coleção.

O grande problema é que o método contains, quando a listagem é grande tem a performance afetada fazendo com que a otimização em vez de ajudar atrapalhe, pois acaba havendo mais trabalho.

Eu gostaria de sugestões de como otimizar esta rotina.

Tentei variar o uso de coleções, gostaria de saber qual é a mais rápida pra consulta, tentei com a LinkedList e com a CopyOnWriteArrayList, mas mesmo assim a performance esta critica, será que seria mais rapido usar um array comum?([]).

So para enriquecer as informações, para inserir no banco quando o mesmo esta vazio, é bastante rápido.

Att. Paulo

Algum tempo atrás eu vi aqui no GUJ um post sobre arrays de string muito legal.

http://www.guj.com.br/posts/list/145548.java#784298

Veja se não te dá uma luz!

Paulo,

Estou supondo que

  1. a lista de arquivos é suficientemente pequena para você poder pô-la toda em memória, e
  2. todos os arquivos têm nomes diferentes entre si (se os nomes não forem diferentes, mas os diretórios forem, então inclua também a informação de diretórios).

Se isso for verdade, então:

A) Faça uma consulta no banco para pegar todos os nomes de arquivos (deve ser rápido) e ponha isso em um TreeSet ou HashSet
B) Liste o tal diretório e ponha a lista de arquivos em outro TreeSet ou HashSet
C) Existe um método na interface Set que serve para obter a diferença entre dois conjuntos. No seu caso, você quer os arquivos novos, ou seja, a diferença entre o conjunto obtido na operação B, e o conjunto obtido na operação A. Essa é a lista de arquivos novos.

Vou dar um exemplo bem bobo com strings. Acho que você é esperto suficiente para particularizar isso para seu caso.

import java.util.*;

class DiferencaConjuntos {
    public static void main (String[] args) {
         Set<String> anterior = new TreeSet<String>();
         Set<String> corrente = new TreeSet<String>();
         // Preenchendo o conjunto "anterior" - esta é a listagem antiga, que você leu do banco
         anterior.add ("explorer.exe");
         anterior.add ("notepad.exe");
         anterior.add ("regedit.exe");
         anterior.add ("winhelp.exe");
         // Preenchendo o conjunto "corrente" - esta é a listagem nova, que você leu do disco
         corrente.add ("notepad.exe");
         corrente.add ("explorer.exe");
         corrente.add ("calc.exe");
         corrente.add ("control.exe");
         // Queremos determinar os "novos" arquivos - são a diferença entre 
         Set<String> novos = new TreeSet<String>();
         novos.addAll (corrente); // primeiro copiamos o conjunto "corrente" em "novos"...
         novos.removeAll (anterior); // agora determinamos a diferença entre "novos" e "anterior"
         System.out.println (novos); // deve imprimir "calc.exe, control.exe" que são os novos arquivos.
         // Outra forma de obter os novos arquivos:
         for (String arquivo : novos) {
            System.out.println (arquivo); // imprime "calc.exe" e a seguir "control.exe"
         }
    }
}