2013-01-12 23 views
11

Tôi đã phát hiện ra một vấn đề hiệu suất với các truy vấn gốc và ngủ đông trên Oracle. Khi tôi thực hiện một truy vấn SQL phức tạp với một số tham số trên TOAD, tôi nhận được kết quả theo mili giây. Tuy nhiên, khi tôi thực hiện cùng một truy vấn bằng cách sử dụng Hibernate thời gian này được tăng lên rất nhiều (lên đến bốn giây hoặc thậm chí nhiều hơn).Hiệu suất chậm trên Hibernate + Java nhưng nhanh khi tôi sử dụng TOAD với cùng một truy vấn Oracle gốc

Truy vấn SQL của tôi khá phức tạp, trả về một giá trị duy nhất (do đó, vấn đề không liên quan đến thời gian cần thiết cho các lớp instation) và nó chứa một số tham số với định dạng ': nameParameter'. Truy vấn này được lưu trữ trong một String. Ví dụ:

String myNamedNativeQuery = "select count(*) from tables "+ 
          "where column1 = :nameParameter1 "+ 
          "and column2 = :nameParameter2"; 
          //actually my sentence is much more complex!! 

Khi tôi thực thi câu trên TOAD, nó được giải quyết sau vài miligiây. Nhưng sử dụng câu này với Hibernate

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 

query.setParameter(nameParameter1, value1); 
query.setParameter(nameParameter2, value2); 

query.uniqueResult(); 

là cần thiết vài giây để có được kết quả tương tự.

Tôi nhận ra nếu tôi thay thế các tham số trực tiếp trên truy vấn gốc và sau đó tôi thực thi câu bằng Hibernate thời gian giảm đáng kể. Nó sẽ là một cái gì đó như thế:

String strQuery = session.getNamedQuery("myNamedNativeQuery").getQueryString(); 

myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter1", value1); 
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter2", value2); 

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 
query.uniqueResult(); 

Bất kỳ ai biết điều gì đang xảy ra?

Xin cảm ơn trước.

PS: Phiên bản Oracle là 9i và Hibernate 3.2

+1

lần lượt tùy chọn "hiển thị sql" với chế độ ngủ đông. Nó sẽ cho bạn thấy truy vấn mà hibernate đang chạy và sẽ cung cấp cho bạn thông tin chi tiết về lý do tại sao quá trình này mất quá nhiều thời gian. –

Trả lời

6

Tôi nghĩ rằng những gì đang xảy ra với mã này:

SQLQuery query = session.createSQLQuery("myNamedNativeQuery"); 
query.setParameter(nameParameter1, value1); 
query.setParameter(nameParameter2, value2); 
query.uniqueResult(); 

là thế này:

tại dòng 1: một kế hoạch truy vấn được tạo ra dựa trên một số giá trị mong đợi cho các thông số được đặt tên của bạn.

tại dòng 4: truy vấn được thực thi với giá trị 1 và value2, nhưng các giá trị đó không phải là "giá trị tốt" cho kế hoạch truy vấn được xây dựng tại dòng 1 và cơ sở dữ liệu đang thực hiện kế hoạch rất không phù hợp cho thực tế giá trị và phải mất rất nhiều thời gian.

Tại sao?

Nhìn vào mã nguồn của HibernateSessionImpl.createSQLQuery(...) tôi thấy dòng mã này:

SQLQueryImpl query = new SQLQueryImpl(
       sql, 
         this, 
         factory.getQueryPlanCache().getSQLParameterMetadata(sql) 
     ); 

được gọi getQueryPlanCache() với một số parameterMetaData. Tôi giả định rằng siêu dữ liệu này không phải là đủ tốt.

+0

Thú vị ... Vậy, thực hành tốt nhất là gì trong những trường hợp này? Có thể thay thế các tham số bằng các giá trị của chúng trước khi gọi hàm createSQLQuery()? – Sobrino

+0

Có lẽ việc chia sẻ con trỏ thích ứng sẽ giúp ích. Nhưng tính năng đó không khả dụng cho đến 11g. –

+0

Theo các thử nghiệm của tôi, tình huống này cũng xảy ra khi sử dụng session.getNamedQuery ('myNamedQuery'). Dường như Hibernate đang lưu vào bộ nhớ cache các kế hoạch truy vấn và với một số tham số, kế hoạch truy vấn được chọn không phải là tốt nhất. Vì vậy, nó sẽ có thể cấu hình bộ nhớ cache kế hoạch truy vấn? – Sobrino

0

câu trả lời của tôi với bạn là:

Remove tất cả các tham số ràng buộc và sử dụng StatelessSession thay vì phiên

Sử dụng sqlquery thay vì truy vấn với SQL đầy đủ bao gồm tham số giá trị

StatelessSession session = sessionFactory.openStatelessSession(); 

Tôi có vấn đề tương tự và cho đến khi tôi nhận được giải pháp tốt hơn, đây là những gì tôi quản lý để làm cho nó hoạt động. Xem Hibernate parameterized sql query slow and active oracle sessions

Các vấn đề liên quan