Về cơ bản, chiến lược mặc định của oracle cho các lọ ojdbc gần đây là "phân bổ trước" một mảng cho mỗi hàng "tìm nạp trước" có khả năng chứa kích thước lớn nhất có thể trả về từ truy vấn đó. Đối với tất cả các hàng. Vì vậy, trong trường hợp của tôi, tôi có một số VARCHAR2 (4000) trong đó và 50 luồng (Statements) * 3 cột của varchar2's * 4000 đang thêm tới hơn gigabyte RAM với setFetchSize là vài trăm [yikes]. Dường như không có tùy chọn nào để nói "không phân bổ trước mảng đó, chỉ sử dụng kích thước khi chúng xuất hiện." Ojdbc thậm chí còn giữ các bộ đệm được phân bổ trước này xung quanh giữa các trạng thái chuẩn bị (bộ nhớ đệm / kết nối) để nó có thể sử dụng lại chúng. Chắc chắn là một con heo nhớ.
Một cách giải quyết:sử dụng setFetchSize
đến một số lượng lành mạnh. Mặc định là 10, có thể khá chậm trên các kết nối có độ trễ cao. Cấu hình và chỉ sử dụng setFetchSize càng cao càng tốt để cải thiện tốc độ đáng kể.
Một giải pháp khác là xác định kích thước cột thực tế tối đa, sau đó thay thế truy vấn bằng (giả sử 50 là kích thước thực tế tối đa đã biết) select substr(column_name, 0, 50)
Những việc khác bạn có thể làm:giảm số lượng hàng tìm nạp trước, tăng java -Xmx
, chỉ chọn những cột bạn thực sự cần.
Sau khi chúng tôi có thể sử dụng ít nhất 400 tìm nạp trước [hãy đảm bảo lập hồ sơ để xem những con số nào phù hợp với bạn, với độ trễ cao, chúng tôi đã thấy những cải tiến lên đến kích thước tìm nạp trước 3-4K] trên tất cả các truy vấn, hiệu suất được cải thiện đáng kể.
Tôi cho rằng nếu bạn muốn thực sự tích cực chống lại các hàng "thực sự dài" thưa thớt, bạn có thể truy vấn lại khi bạn gặp những hàng lớn [hiếm] này.
Thông tin chi tiết về ad nauseum tại đây