Použití setFirstResult a setMaxResults je vaše jediná možnost, o které vím.
Posouvatelná sada výsledků by tradičně přenášela řádky do klienta pouze podle potřeby. Bohužel MySQL Connector/J to ve skutečnosti zfalšuje, provede celý dotaz a přenese ho ke klientovi, takže ovladač má ve skutečnosti celou sadu výsledků načtenou v RAM a odkape vám ji (důkazem jsou vaše problémy s nedostatkem paměti) . Měli jste správný nápad, jsou to jen nedostatky v ovladači Java MySQL.
Nenašel jsem způsob, jak to obejít, a tak jsem šel s načítáním velkých kusů pomocí běžných metod setFirst/max. Omlouvám se, že přináším špatné zprávy.
Jen se ujistěte, že používáte bezstavovou relaci, aby nedocházelo k mezipaměti na úrovni relace nebo nečistému sledování atd.
EDIT:
Vaše UPDATE 2 je to nejlepší, co dostanete, pokud se nevymaníte z MySQL J/Connector. I když není důvod, abyste nemohli zvýšit limit na dotaz. Pokud máte dostatek paměti RAM k udržení indexu, měla by to být poněkud levná operace. Mírně bych to upravil a vzal dávku po druhé a použil nejvyšší id této dávky k odebrání další dávky.
Poznámka:Toto bude fungovat pouze v případě jiné_podmínky použijte rovnost (žádné podmínky rozsahu nejsou povoleny) a jako id použijte poslední sloupec indexu .
select *
from person
where id > <max_id_of_last_batch> and <other_conditions>
order by id asc
limit <batch_size>