Dúvidas/Problemas com performance com inserção de grande quantidade de registros em SQLite

Boa tarde,

Em meu aplicativo eu tenho um processo que faz requisições ao web service, chamando web método a web método e recebendo o retorno faz o tratamento necessário e grava no banco SQLite.
Hoje ela está funcionando dessa maneira:

Eu tenho uma Activity que chama um AsyncTask no AsyncTask eu faço a chamada:

Cliente cliente = new Cliente(); cliente.setWsRepresentante(getSharedPreferences("PREFS_PRIVATE", MODE_PRIVATE).getInt("representante", 0)); cliente.importarDados();

Na classe de cliente, eu tenho o método importarDados() que faz o Override do método da sua super classe que no caso é a Persistência:

[code]
@Override
public void importarDados(){

	this.setWsNomeMetodo("GetClientes");
	this.setTabela(this.getClass().getSimpleName());
	this.setCamposPK(new String[]{"Identificacao"});
	super.importarDados();
}[/code]

E na minha classe Persistencia eu tenho o método de importação(Hoje o processo está assim):

[code]DataBase = new DadosBD(Singleton.getContextoAplicacao());
SoapObject request = new SoapObject(this.getWsNameSpace(), this.getWsNomeMetodo());
request.addProperty(“representante”, WsRepresentante);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.implicitTypes = false;
envelope.setOutputSoapObject(request);

		HttpTransportSE httpTransport = new HttpTransportSE(this.getWsUrl());
		httpTransport.call(this.getWsNameSpace() + "" + this.getWsNomeMetodo(), envelope);
		SoapObject result = (SoapObject) envelope.getResponse();
		
		if (result != null) {
			
			int resultCount = result.getPropertyCount();
			
			if(resultCount > 0){
				
				SoapObject objResult = new SoapObject();
				SoapObject objSoap = new SoapObject();

				objResult = (SoapObject) result.getProperty(1);
				if(objResult.getPropertyCount() > 0){
					
					objSoap = (SoapObject) objResult.getProperty(0);
					int propertyResultCount = objSoap.getPropertyCount();
	                
	                if (propertyResultCount > 0){
	                	
	                	this.Dados = new ContentValues();
	                    
	        	    	for (int currentProperty = 0; currentProperty < propertyResultCount; currentProperty++) {
	       	    		 
	                        SoapObject obj = (SoapObject) objSoap.getProperty(currentProperty);
	                        int attributeResultCount = obj.getPropertyCount();
	                        
	                        for(int index = 0; index < attributeResultCount; index++){
	                        	
	                        	PropertyInfo pi = new PropertyInfo();
	                        	obj.getPropertyInfo(index, pi);
	                        	this.Dados.put(pi.name.toString(), ((pi.getValue().toString().equals("anyType{}")?(""):(pi.getValue().toString()))));
	                        }
	                        
	                        for (int i = 0; i < this.getCamposPK().length; i++) {
	                        	if(condicao=="")
	                        		condicao = condicao + CamposPK[i].toString() + " = '" + this.Dados.get(CamposPK[i].toString()) + "'";
	                        	else
	                        		condicao = condicao + " AND " + CamposPK[i].toString() + " = '" + this.Dados.get(CamposPK[i].toString()) + "'";
	                        }
	                        
	                        this.setTabelaSelecao(condicao);
	                        RsAtual = DataBase.ExecSelect(Tabela, TabelaColunaComposta, TabelaSelecao, TabelaSelecaoArgumentos, TabelaGroupBy, TabelaHaving, TabelaOrderBy);
	                        
	                        if(RsAtual.moveToNext()) {
	                        	Encontrou = true;
	                        	RsAtual.close();
	                        }
	                        
	                        if(!Encontrou){
	                        	
	                        	DataBase.ExecInsert(Tabela, TabelaColunaSimples, Dados);
	                        	RsAtual.close();
	                        }else{
	                        	
	                        	this.setTabelaWhere(this.getTabelaSelecao().toString());
	                        	DataBase.ExecUpdate(Tabela, Dados, TabelaWhere, TabelaWhereArgumentos);
	                        	RsAtual.close();
	                        }
	                        condicao = "";
	                        Encontrou = false;
	                    }
	                }
				}
			}
		}[/code]

Só que por exemplo dependendo do método chamado no WS ele retorna coisa de 4000 mil registros e isso demora coisa de 3 minutos para ser inserido no banco de dados. E ainda não tenho só esse método são 10 tabelas a serem preenchidas e dá mais ou menos 10 minutos ou mais.

Pesquisando na internet me sugeriram InsertHelper() implementei o mesmo fazendo o uso de transações, mas como podem ver eu preciso receber os dados validar e se já existir no banco atualizar o registro. E não conseguia fazer update dos registros utilizando o InsertHelper(). Então pesquisando um pouco mais vi bastante gente falando que conseguiram arrumar o problema de performance utilizando SQLiteStatement que é bem mais leve e chega a inserir 4000 registros em milissegundos.

Então primeiramente qual seria a melhor maneira de fazer esse tipo de insert?

Só que hoje minha Classe de Persistencia faz o uso de uma instância do meu banco de dados. E nele eu tenho os meus métodos:

[code] public void ExecInsert(String tableName, String tableColumn, ContentValues valores){

	database.insert(tableName, tableColumn, valores);
}

public void ExecUpdate(String tableName, ContentValues valores, String whereClause, String[] whereArgs){
	
	database.update(tableName, valores, whereClause, whereArgs);
}

public void ExecDelete(String tableName, String whereClause, String[] whereArgs){
	
	database.delete(tableName, whereClause, whereArgs);
}[/code]

Alguém já teve problema semelhante?

Obrigado desde já.

O que demora não é a consulta?

Normalmente é bem rapido para inserir. Separe a consulta da inserção e meça-os separadamente.

[quote=Marky.Vasconcelos]O que demora não é a consulta?

Normalmente é bem rapido para inserir. Separe a consulta da inserção e meça-os separadamente.[/quote]

Marky a consulta que você diz seria este trecho de código abaixo?

[code] this.setTabelaSelecao(condicao);
RsAtual = DataBase.ExecSelect(Tabela, TabelaColunaComposta, TabelaSelecao, TabelaSelecaoArgumentos, TabelaGroupBy, TabelaHaving, TabelaOrderBy);

	                        if(RsAtual.moveToNext()) {
	                        	Encontrou = true;
	                        	RsAtual.close();
	                        }[/code]

Então porque antes eu estava utilizando o método:

[code] public void ExecInsert(String tableName, String tableColumn, ContentValues valores){

	database.insert(tableName, tableColumn, valores);
}[/code]

Esse database é um:

dbHelper = new DbHelper(ctx, DadosBD.DataBaseName, null, DadosBD.DataBaseVersion, DadosBD.ScriptDataBaseCreate, DadosBD.ScriptDataBaseDelete); database = dbHelper.getWritableDatabase();

E conforme pesquisei esse é o método mais lento de inserção, utilizando o ContentValues e fazendo a inserção dos registros.

Inclusive acabei de fazer um teste, fazendo a requisição da tabela Cidade que tinham 2805 registros.
Utilizando o SQLiteStatement ele fez essa inserção em bem menos de 30 segundos.

Antes demorava de 2 a 3 minutos.

Mas estou com problemas em como fazer da forma mais dinâmica possível até porque é 1 método para todas as tabelas.