Tôi đã đấu tranh trong vài ngày với một truy vấn trên hibernate dựa vào cơ sở dữ liệu Oracle. Một cái gì đó như thế này được sử dụng để nạp các bản ghi vào lưới.Hibernate tham số sql truy vấn các phiên oracle chậm và hoạt động
SELECT
fields
FROM
tables and JoinedTables
WHERE
Field1 >= :value1
AND Field2 = :value2
AND Field3 = :value3
Order By MaintTable.Id Desc
Sử dụng phương pháp này trong phương pháp Spring Java + Hibernate 4.2.
SQLQuery query = (SQLQuery) session.createSQLQuery(querySql)
.addEntity(CertificateViewEnt.class)
.setParameter("value1", firstCertificateRecordDate)
.setParameter("value2", certType.toUpperCase())
.setParameter("value3", deleted? 1:0);
Mỗi trường được lọc được lập chỉ mục chính xác và tạo Chỉ mục chức năng trên Maintable.Id Descendent để cải thiện hiệu suất.
Lúc đầu, tôi nghĩ rằng nó là hồ bơi phiên/kết nối không được quản lý một cách chính xác, vì vậy tôi đã thay đổi để StatelessSession và thêm session.close này():
query.setCacheable(false)
.setTimeout(30)
.setReadOnly(true);
...
...
//Pagination
query.setMaxResults(rows);
query.setFirstResult(HelperMethod(page, rows));
result = (List<CertificateViewEnt>) query.list();
session.close();
return result;
Nó không giải quyết nó. Truy vấn chạy một cặp lần ok, nhưng vì một số lý do không xác định và sử dụng các giá trị đã chạy trước đó với thành công, treo, thoát phiên mở trong Oracle (status = ACTIVE) và không thành công khi hết thời gian chờ. Truy vấn tương tự đang chạy với Oracle trên bất kỳ máy khách SQL nào và hàng chục lần với tất cả các kết hợp có thể có của các tham số thực hiện với hiệu suất cực đại, khoảng 400 mili giây, cho 10 bản ghi tại một thời điểm.
Sau khi đọc một số bài viết ở đây và ở đó, link1 [Slow performance on Hibernate + Java but fast when I use TOAD with the same native Oracle query Link2: [query hangs oracle 10g
tôi supected của QueryPlan kém đang được sử dụng bởi Hibernate và quyết định loại bỏ tất cả các bộ lọc sử dụng các tham số ràng buộc và cũng không giải quyết, mặc dù nó tốt hơn một chút. Sau một thời gian bị treo cổ khi di chuyển đến các trang khác như trang 1, 2,3,4, ...
Sau tất cả những gì, tôi nghi ngờ của SQL được tạo ra bằng phương pháp Hibernate của
query.setMaxResults(rows)
query.setFirstResult(SomeHelperMethod(page, rows));
Bởi vì cưa trong nhật ký rằng họ đã được chuyển thành các tham số liên kết với Oracle.
...
Order By Certificado.Id Desc) row_
where rownum <= ?)
where rownum_ > ?
Tôi cũng thấy điều này trong Trace Log
2015-09-15 14:09:53 TRACE QueryPlanCache:200 - Located native-sql query plan in cache (SELECT /*+ INDEX(
và điều này:
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [2] as [VARCHAR] - E
2015-09-15 14:09:53 DEBUG Loader:2031 - bindNamedParameters() 0 -> deleted [3]
2015-09-15 14:09:53 TRACE BasicBinder:84 - binding parameter [3] as [INTEGER] - 0
2015-09-15 14:09:53 TRACE Loader:1931 - Bound [7] parameters total
/*
SLOW here !!! Around 3 secs when query runs in ~0,300 secs via SQL client.
And ACTIVE sessions are left running in Oracle.
*/
2015-09-15 14:09:56 TRACE JdbcCoordinatorImpl:397 - Registering result set [[email protected]]
2015-09-15 14:09:56 TRACE Loader:943 - Processing result set
Cuối cùng tôi đã phải từ bỏ tất cả các params ràng buộc Hibernate và thực hiện pagination tính tùy chỉnh và viết tất cả các SQL để truy xuất các hàng trang và nó chạy và quản lý các phiên db một cách chính xác.
Vì vậy, Câu hỏi của tôi là: Hibernate làm behing những cảnh nào ngăn truy vấn chạy khi nó chạy trên cơ sở dữ liệu? Có bất kỳ vấn đề đã biết nào với các truy vấn tham số ràng buộc không?
Tôi thực sự không muốn viết tất cả mã SQL và buộc phân tích cú pháp khó SQL này, khi tôi có các tham số liên kết.
Một số ghi chú về môi trường: Tomcat và Oracle nằm trên cùng một máy chủ.Vì vậy, kết nối mạng không phải là vấn đề
Hibernate phiên bản 4.2.15 chính thức
Bảng có khoảng 300k REC trong cơ sở dữ liệu dev (1,5m trên sản xuất) và hiển thị các trang 10, 20, 50 REC tại một thời điểm , được sắp xếp theo Primary Key Desc (Chuỗi được tạo ra)
Hy vọng một số chuyên gia Hibernate có thể giúp tôi về điều này để tôi vẫn có thể tin tưởng các truy vấn Hibernate trên các dự án cơ sở dữ liệu lớn. Cảm ơn trước.
Có cùng vấn đề. Trong MySQL Workbench, truy vấn mất 0 ms. Trong Hibernate phải mất 1500ms. –
Lấy tất cả các tham số Hibernate và tự xây dựng truy vấn SQL với tất cả các tham số được đặt trong chuỗi SQL. Nó làm việc cho tôi. Giống như là một truy vấn trường học cũ của JDBC. –
Cảm ơn lời khuyên. Chắc chắn đáng để thử! –