什麼叫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;
通過以上5條select語句,hibernate最後載入了4個customer物件和5個order物件,在記憶體中形成了一幅關聯的物件圖,參見圖2。
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物件白白浪費了許多記憶體空間。
為了解決以上問題,hibernate提供了其他兩種檢索策略:延遲檢索策略和迫切左外連線檢索策略。延遲檢索策略能避免多餘載入應用程式不需要訪問的關聯物件,迫切左外連線檢索策略則充分利用了sql的外連線查詢功能,能夠減少select語句的數目。
什麼叫n 1次select查詢問題
在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列出了customers表和order...
SQL中的n 1次select語句查詢問題
如果當sql 資料庫中select語句數目過多,就會影響資料庫的效能,如果需要查詢n個customer物件,那麼必須執行n 1次select查詢語句,下文就將為您講解這個n 1次select查詢問題。在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入cu...
關於N 1次查詢
1,什麼是n 1次查詢 在使用hibernate,或者ibatis等工具查詢資料庫的時候,由於快取,或者lazyload 懶載入 等原因,可能會造成要查詢n個結果,但是不得不執行n 1次查詢資料庫操作,造成效率低下。2,使用hibernate,什麼時候會產生n 1次查詢 a,使用iterate查詢的...