V zásadě je výchozí strategií Oracle pro nedávné jary ojdbc „předem alokovat“ pole na řádek „předběžného načtení“, které se přizpůsobí největší možné velikosti, kterou lze z tohoto dotazu vrátit. Pro všechny řádky. Takže v mém případě jsem tam měl nějaký VARCHAR2(4000) a 50 vláken (Výpisy) * 3 sloupce varchar2 * 4000 přidávalo více než gigabajty RAM s setFetchSize několik stovek [fuj]. Zdá se, že neexistuje možnost říci „nepřidělujte toto pole předem, pouze použijte velikost tak, jak přicházejí.“ Ojdbc dokonce udržuje tyto předem přidělené vyrovnávací paměti kolem mezi připravenými příkazy (v mezipaměti/připojení), aby je mohl znovu použít. Rozhodně paměťový prase.
Jedno řešení:použijte setFetchSize
do nějaké rozumné částky. Výchozí hodnota je 10, což může být u připojení s vysokou latencí poměrně pomalé. Profilujte a používejte pouze takovou hodnotu setFetchSize, která ve skutečnosti výrazně zvyšuje rychlost.
Dalším řešením je určit maximální skutečnou velikost sloupce a poté nahradit dotaz (za předpokladu, že 50 je známá maximální skutečná velikost) select substr(column_name, 0, 50)
Další věci, které můžete udělat:snížit počet řádků předběžného načtení, zvýšit java -Xmx
vyberte pouze ty sloupce, které skutečně potřebujete.
Jakmile se nám podařilo použít alespoň 400 předběžného načtení [nezapomeňte si vytvořit profil, abyste viděli, jaká čísla jsou pro vás dobrá, s vysokou latencí jsme zaznamenali vylepšení až na velikost předběžného načtení 3–4 kB] u všech dotazů, výkon se dramaticky zlepšil.
Předpokládám, že pokud byste chtěli být skutečně agresivní vůči řídkým „opravdu dlouhým“ řádkům, mohli byste být schopni znovu zadat dotaz, když narazíte na tyto [vzácné] velké řádky.
Podrobnosti ad nauseum zde