Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Usando ScrollableResults do Hibernate para ler lentamente 90 milhões de registros


Usar setFirstResult e setMaxResults é sua única opção que eu conheço.

Tradicionalmente, um conjunto de resultados rolável só transferiria linhas para o cliente conforme necessário. Infelizmente, o MySQL Connector/J realmente o falsifica, ele executa a consulta inteira e a transporta para o cliente, então o driver realmente tem todo o conjunto de resultados carregado na RAM e o alimentará por gotejamento (evidenciado por seus problemas de falta de memória) . Você teve a ideia certa, são apenas falhas no driver java do MySQL.

Eu não encontrei nenhuma maneira de contornar isso, então fui carregando grandes pedaços usando os métodos regulares setFirst/max. Desculpe ser o portador de más notícias.

Apenas certifique-se de usar uma sessão sem estado para que não haja cache de nível de sessão ou rastreamento sujo etc.

EDITAR:

Seu UPDATE 2 é o melhor que você obterá, a menos que você saia do MySQL J/Connector. Embora não haja motivo para que você não possa aumentar o limite da consulta. Desde que você tenha RAM suficiente para manter o índice, essa operação deve ser um pouco barata. Eu modificaria um pouco e pegaria um lote de cada vez e usaria o id mais alto desse lote para pegar o próximo lote.

Observação:isso só funcionará se other_conditions use igualdade (sem condições de intervalo permitidas) e tenha a última coluna do índice como id .
select * 
from person 
where id > <max_id_of_last_batch> and <other_conditions> 
order by id asc  
limit <batch_size>