PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Qual é a maneira mais rápida de recuperar dados sequenciais do banco de dados?

SELECT * FROM table ORDER BY column

Não há razão para estar sugando a tabela inteira para a RAM. Basta abrir um cursor e começar a ler. Você pode jogar jogos com tamanhos de busca e outros, mas o banco de dados ficará feliz em manter seu lugar enquanto você processa suas linhas.

Adendos:

Ok, se você estiver usando Java, então eu tenho uma boa ideia de qual é o seu problema.

Primeiro, apenas usando Java, você está usando um cursor. Isso é basicamente o que é um ResultSet em Java. Alguns ResultSets são mais flexíveis do que outros, mas 99% deles são simples, encaminham apenas ResultSets que você chama de 'próximo' para obter cada linha.

Agora quanto ao seu problema.

O problema é especificamente com o driver Postgres JDBC. Eu não sei por que eles fazem isso, talvez seja especificação, talvez seja outra coisa, mas independentemente disso, o Postgres tem a curiosa característica de que se sua conexão tiver autoCommit definido como true, então o Postgres decide sugar todo o resultado definido no execute o método ou o primeiro próximo método. Não é realmente importante onde, apenas que, se você tiver um gazilhão de linhas, obterá uma boa exceção OOM. Não ajuda.

Isso pode facilmente ser exatamente o que você está vendo, e eu aprecio como isso pode ser bastante frustrante e confuso.

A maioria das conexões padrão é autoCommit =true. Em vez disso, basta definir autoCommit como false.
Connection con = ...get Connection...
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("SELECT * FROM table ORDER BY columm");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
    String col1 = rs.getString(1);
    ...and away you go here...
}
rs.close();
ps.close();
con.close();

Observe a distinta falta de tratamento de exceções, deixada como exercício para o leitor.

Se você quiser mais controle sobre quantas linhas são buscadas por vez na memória, você pode usar:
ps.setFetchSize(numberOfRowsToFetch);

Brincar com isso pode melhorar seu desempenho.

Certifique-se de ter um índice apropriado na coluna que você usa no ORDER BY se você se importa com o sequenciamento.