Performance SQLITE Android

Pessoal estou desenvolvendo um app de leitura de condigo de barras em um coletor Android, estou com um problema de performance quando minha base de dados chega perto dos 20 mil registros.

Na tela do coletor aparece algumas informações como quantidade de código de barras lidos, nome do produto etc, também verifico se aquele código já foi lido anteriormente, ou seja, a cada leitura eu tenho que fazer o select na tabela toda e verificar se já foi lido, contar a quantidade total de registros, contar a quantidade daquele produto lido, e outros.

Toda vez que o operador aperta o gatilho do coletor eu faço todos essas validações e consultas antes de inserir esse novo registro no banco, quando tenho até 10 mil registros está tranquilo, mais quando vai chegando próximo de 20 mil, esta demorado.

Como posso deixar isso mais performático?

Segue os trechos de código:

//chamada dos metodos de quantidade
tvQtdTotal.setText(String.valueOf(apontamentoDao.getCountQtdTotal(usuario, "N", dataabate)));
tvQtdProd.setText(String.valueOf(apontamentoDao.getCountQtdProd(usuario, "N", dataabate, String.valueOf(codprod))));

//verifica se o código de barras já foi lido anteriormente
if (apontamentoDao.getLeituraRepetida(result)){...}

//verifica se é igual ao ultimo registro lido
if (apontamentoDao.getUltimaLeitura(result)) {...}


//metodos

public int getCountQtdTotal(String turno, String etirepetida, String dataabate) {
    Log.d(TAG, "ApontamentoDao.getCountQtdTotal");
    SQLiteDatabase db = new Db(ctx).getWritableDatabase();

    String selection = "turno = ? AND etirepetida = ? AND dataabate = ?";
    String[] selectionArgs = {turno, etirepetida, dataabate};

    Cursor c = db.query(nomeTabela, null, selection, selectionArgs, null, null, null);
    int result = c.getCount();

    c.close();
    db.close();
    return result;
}

public int getCountQtdProd(String turno, String etirepetida, String dataabate, String codprod) {
    Log.d(TAG, "ApontamentoDao.getCountQtdProd");
    SQLiteDatabase db = new Db(ctx).getWritableDatabase();

    String selection = "turno = ? AND etirepetida = ? AND dataabate = ? AND codprod = ?";
    String[] selectionArgs = {turno, etirepetida, dataabate, codprod};

    Cursor c = db.query(nomeTabela, null, selection, selectionArgs, null, null, null);
    int result = c.getCount();

    c.close();
    db.close();
    return result;
}

public boolean getLeituraRepetida(String novaLeitura) {
    Log.d(TAG, "ApontamentoDao.getLeituraRepetida");
    SQLiteDatabase db = new Db(ctx).getWritableDatabase();
    Cursor rs = db.query(nomeTabela, colunas, "leitura=?", new String[]{novaLeitura}, null, null, null);
    boolean retorno = false;

    if (rs.moveToFirst()) {
        retorno = true;
    }
    rs.close();
    db.close();
    return retorno;
}

public boolean getUltimaLeitura(String novaLeitura) {
    Log.d(TAG, "ApontamentoDao.getUltimaLeitura");
    SQLiteDatabase db = new Db(ctx).getWritableDatabase();
    Cursor rs = db.rawQuery("select * from tbapontamentos where id = (select max(id) from tbapontamentos)", null);

    ApontamentoModelo apontamentoModelo = null;
    if (rs.moveToFirst()) {

        apontamentoModelo = new ApontamentoModelo();
        apontamentoModelo.setId(rs.getInt(rs.getColumnIndex("id")));
        apontamentoModelo.setCodprod(rs.getInt(rs.getColumnIndex("codprod")));
        apontamentoModelo.setDataleitura(rs.getString(rs.getColumnIndex("dataleitura")));
        apontamentoModelo.setLeitura(rs.getString(rs.getColumnIndex("leitura")));
        apontamentoModelo.setTurno(rs.getString(rs.getColumnIndex("turno")));
        apontamentoModelo.setDataabate(rs.getString(rs.getColumnIndex("dataabate")));
        apontamentoModelo.setEtirepetida(rs.getString(rs.getColumnIndex("etirepetida")));
        apontamentoModelo.setEsteira(rs.getString(rs.getColumnIndex("esteira")));
        apontamentoModelo.setSincronizado(rs.getString(rs.getColumnIndex("sincronizado")));
    }

    if (apontamentoModelo != null && apontamentoModelo.getLeitura().equals(novaLeitura))
        return true;
    else
        return false;
}

É fato que com um número muito grande de dados em uma tabela ou banco, em algum momento o teu sistema apresentará lentidão.
Não sei se o SQLite é o mais indicado para armazenar a quantidade de dados que você pretende manipular, bem como, não consigo dizer se toda a culpa é do SQLite.
Já tentou incluir logs contendo a hora (hora, minuto, segundo) em que a ação inicia e conclui? Para ver se o gargalo é o SQLite ou algo no código mesmo?

Sim, os gargalos estão nesses trechos de código que postei acima, quando comento eles, tudo flui normalmente.

Qual o tamanho disso em GB?

Se não me engano SQLlite tem um limite de 5GB. A partir daí você tem que usar um banco de dados de verdade.

Estou testando uma base com 30 mil registros é tem apenas 3,94 MB. É muito pequeno, ele guarda apenas números e textos…

Então o problema deve ser na sua app.

Eu não sei o que sua app faz, na verdade da pra ter uma vaga ideia, mas uma app tem que ter um propósito específico, talvez sua app anda fazendo coisa demais?