Multiplo insert - performace

Boa Tarde Pessoal,

estou fazendo multimplos insert’s em jpa, utilizando o seguinte metodo.

	private Tmp_Ntc gravar(List<Tmp_Ntc> listaTmp){
		Tmp_Ntc tmp = new Tmp_Ntc();
		List<Tmp_Ntc> listNtc = new ArrayList<Tmp_Ntc>();
		
		listNtc = listaTmp;
		
		EntityManager entityManager = getEntityManager();
		
		
		
		entityManager.getTransaction().begin();
		
		int vConta = 0;
		for (int i = 0; i < listNtc.size(); i++){
			
			tmp = listNtc.get(i);
			//System.out.println(tmp.getNUM_NTC());
			
			if (tmp.getLOGIN() != null){
				tmp = entityManager.merge(tmp);
			}else{
				entityManager.persist(tmp);
			}
			
			if (vConta == 500){
				entityManager.getTransaction().commit();
				entityManager.clear();          
				entityManager.getTransaction().begin();
				vConta = 0;
				System.out.println("Atingiu 500");
			}else{
				vConta++;
			}
		}
		
		entityManager.getTransaction().commit();
		return tmp;
	}

Em media ao inserir 30.000 registros em torno de 18 minutos,
Existe alguma forma de melhorar está performace ?

grato,

por que você commita a transação e abre uma nova a cada inserção? Por que não faz tudo em uma transação só? ou pelo menos em lotes maiores caso isso realmente seja uma preocupação

Tente arrancar fora essa restrição de a cada 500 fazer um commit e tentar tudo na mesma transação e mude esse for com índice para o foreach.

Em vez de só melhorar o desempenho, procure melhorar o próprio código em si:

  • Você não precisa de outro contador pra ver se já chegou a 500, use a variável “i” e veja se o resto da divisão por 500 tem resto zero
  • Melhor ainda, não use o for com indexador porque nem sempre a lista que você vai receber é uma lista cujo acesso pelo índice é rápido (como ArrayList, por exemplo). Use o foreach ou, se não estiver usando Java 5 pelo menos, use um while com um iterator.
  • Por que o método retorna o Tmp_Ntc?
  • Em vez daquele “if (tmp.getLOGIN() != null)”, pense em usar um “insert or update” do JPA (não me lembro agora o nome exato do método, mas ele deixa intuitivo que está fazendo um insert ou update). Isso, claro, se o login for o ID de Tmp_Ntc
  • Utilize algo melhor pra logar as coisas. Um simples Logger já basta. Usar System.out pra isso é o mesmo que codificar no Notepad.
  • Você não precisa ficar limpando o cache de primeiro nível a toda hora. Toda vez que você faz um commit ele é limpo.
  • Também não precisa inicializar as variáveis Tmp_Ntc tmp e listNtc. Apesar de isso não fazer nem cosquinhas no mindinho desse método.