Menggunakan setFirstResult dan setMaxResults adalah satu-satunya opsi yang saya ketahui.
Secara tradisional, kumpulan hasil yang dapat digulir hanya akan mentransfer baris ke klien sesuai kebutuhan. Sayangnya Konektor MySQL/J benar-benar memalsukannya, ia mengeksekusi seluruh kueri dan mengirimkannya ke klien, jadi driver sebenarnya memiliki seluruh hasil yang dimuat dalam RAM dan akan memberikannya kepada Anda (dibuktikan dengan masalah kehabisan memori Anda) . Anda memiliki ide yang tepat, hanya saja kekurangan pada driver java MySQL.
Saya tidak menemukan cara untuk menyiasatinya, jadi lanjutkan dengan memuat potongan besar menggunakan metode setFirst/max biasa. Maaf menjadi pembawa berita buruk.
Pastikan untuk menggunakan sesi stateless sehingga tidak ada cache level sesi atau pelacakan kotor, dll.
EDIT:
PEMBARUAN 2 Anda adalah yang terbaik yang akan Anda dapatkan kecuali Anda keluar dari MySQL J/Connector. Meskipun tidak ada alasan Anda tidak dapat mencapai batas kueri. Asalkan Anda memiliki cukup RAM untuk menampung indeks, ini akan menjadi operasi yang agak murah. Saya akan memodifikasinya sedikit, dan mengambil batch pada satu waktu, dan menggunakan id tertinggi dari batch itu untuk mengambil batch berikutnya.
Catatan:ini hanya akan berfungsi jika kondisi_lain gunakan kesetaraan (tidak ada ketentuan rentang yang diizinkan) dan jadikan kolom terakhir indeks sebagai id .
select *
from person
where id > <max_id_of_last_batch> and <other_conditions>
order by id asc
limit <batch_size>