SQL查詢語句臃腫問題淺析

edithfang發表於2014-10-30
如果當SQL資料庫中select語句數目過多,就會影響資料庫的效能,如果需要查詢n個Customer物件,那麼必須執行n+1次select查詢語句。在Session的 快取中存放的是相互關聯的物件圖。預設情況下,當Hibernate從資料庫中載入Customer物件時,會同時載入所有關聯的Order物件。以 Customer和Order類為例,假定ORDERS表的CUSTOMER_ID外來鍵允許為null,圖1列出了CUSTOMERS表和ORDERS表中的記錄。



以下Session的find()方法用於到資料庫中檢索所有的Customer物件: 
 List customerLists=session.find("from Customer as c");
執行以上find()方法時,Hibernate將先查詢CUSTOMERS表中所有的記錄,然後根據每條記錄的ID,到ORDERS表中查詢有參照關係的記錄,Hibernate將依次執行以下select語句:  
select * from CUSTOMERS;
  select * from ORDERS where CUSTOMER_ID=1;
  select * from ORDERS where CUSTOMER_ID=2;
  select * from ORDERS where CUSTOMER_ID=3;
  select * from ORDERS where CUSTOMER_ID=4;
select語句的數目太多,需要頻繁的訪問資料庫,會影響檢索效能。如果需要查詢n個Customer物件,那麼必須執行n+1次select查詢語句。這就是經典的n+1次select查詢問題。

通過以上5條select語句,Hibernate最後載入了4個Customer物件和5個Order物件,在記憶體中形成了一幅關聯的物件圖。



Hibernate在檢索與Customer關聯的Order物件時,使用了預設的立即檢索策略。這種檢索策略存在兩大不足:

1、select語句的數目太多,需要頻繁的訪問資料庫,會影響檢索效能。如果需要查詢n個Customer物件,那麼必須執行n+1次select查詢語 句。這就是經典的n+1次select查詢問題。這種檢索策略沒有利用SQL的連線查詢功能,例如以上5條select語句完全

可以通過以下1條 select語句來完成:
select * from CUSTOMERS left outer join ORDERS
on CUSTOMERS.ID=ORDERS.CUSTOMER_ID
以上select語句使用了SQL的左外連線查詢功能,能夠在一條select語句中查詢出CUSTOMERS表的所有記錄,以及匹配的ORDERS表的記錄。

2、在應用邏輯只需要訪問Customer物件,而不需要訪問Order物件的場合,載入Order物件完全是多餘的操作,這些多餘的Order物件白白浪費了許多記憶體空間。

傾情推薦EMSSoftware公司旗下SQL資料量管理工具來解決資料庫各項問題。
相關閱讀
評論(1)

相關文章