Mysql
 sql >> Database >  >> RDS >> Mysql

Utilizzo di ScrollableResults di Hibernate per leggere lentamente 90 milioni di record

L'uso di setFirstResults e setMaxResults è l'unica opzione di cui sono a conoscenza.

Tradizionalmente un set di risultati scorrevole trasferirebbe le righe al client solo in base alle esigenze. Sfortunatamente MySQL Connector/J in realtà lo falsifica, esegue l'intera query e la trasporta al client, quindi il driver ha effettivamente l'intero set di risultati caricato nella RAM e te lo alimenterà (evidenziato dai tuoi problemi di memoria esaurita) . Hai avuto l'idea giusta, sono solo carenze nel driver java MySQL.

Non ho trovato alcun modo per aggirare questo problema, quindi sono andato a caricare blocchi di grandi dimensioni utilizzando i normali metodi setFirst/max. Mi dispiace essere portatore di cattive notizie.

Assicurati solo di utilizzare una sessione stateless in modo che non ci sia cache a livello di sessione o tracciamento sporco, ecc.

MODIFICA:

Il tuo UPDATE 2 è il meglio che otterrai a meno che non esca da MySQL J/Connector. Anche se non c'è motivo per cui non puoi aumentare il limite della query. A condizione che tu abbia abbastanza RAM per contenere l'indice, questa dovrebbe essere un'operazione alquanto economica. Lo modificherei leggermente, prenderò un batch alla volta e userei l'ID più alto di quel batch per prendere il batch successivo.

Nota:funzionerà solo se altre_condizioni utilizzare l'uguaglianza (nessuna condizione di intervallo consentita) e avere l'ultima colonna dell'indice come id .

select * 
from person 
where id > <max_id_of_last_batch> and <other_conditions> 
order by id asc  
limit <batch_size>