基本的に、最近のojdbc jarに対するオラクルのデフォルトの戦略は、「プリフェッチ」行ごとに配列を「事前割り当て」することです。これは、そのクエリから返される可能性のある最大サイズに対応します。すべての行に対して。したがって、私の場合、そこにVARCHAR2(4000)があり、50スレッド(ステートメント)*3列のvarchar2* 4000は、数百[yikes]のsetFetchSizeでギガバイトを超えるRAMを追加していました。 「その配列を事前に割り当てないで、入ってくるサイズを使用する」というオプションはないようです。 Ojdbcは、これらの事前に割り当てられたバッファを準備されたステートメント間に保持します。 (キャッシュ/接続)ので、それらを再利用できます。間違いなくメモリホッグ。
1つの回避策:setFetchSize
を使用します ある程度の正気の量に。デフォルトは10ですが、これは待ち時間の長い接続では非常に遅くなる可能性があります。プロファイルを作成し、実際に速度を大幅に向上させるのと同じ高さのsetFetchSizeのみを使用します。
別の回避策は、実際の最大列サイズを決定してから、クエリを次のように置き換えることです(50が既知の最大実際サイズであると想定)select substr(column_name, 0, 50)
あなたができる他のこと:プリフェッチ行の数を減らし、java -Xmx
を増やします パラメータは、実際に必要な列のみを選択します。
すべてのクエリで少なくともプリフェッチ400を使用できるようになると[プロファイリングして適切な数値を確認し、レイテンシが高くなると、プリフェッチサイズ3〜4Kまで改善されます]、パフォーマンスが劇的に向上しました。
疎な「非常に長い」行に対して本当に積極的になりたい場合は、これらの[まれな]大きな行に遭遇したときに再クエリできる可能性があると思います。
詳細広告の吐き気