資料庫查詢的N+1問題
阿新 • • 發佈:2018-12-30
轉載自:https://blog.csdn.net/w05980598/article/details/79647291
簡介
在orm框架中,比如hibernate和mybatis都可以設定關聯物件,比如user物件關聯dept假如查詢出n個user,那麼需要做n次查詢dept,查詢user是一次select,查詢user關聯的dept,是n次,所以是n+1問題,其實叫1+n更為合理一些。
mybatis配置
UserMapper.xml
<resultMap id="BaseResultMap" type="testmaven.entity.User"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="age" jdbcType="INTEGER" property="age" /> <result column="dept_id" jdbcType="INTEGER" property="deptId" /> <association property="dept" column="dept_id" fetchType="eager" select="testmaven.mapper.DeptMapper.selectByPrimaryKey" ></association> </resultMap> DeptMapper.xml <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > select <include refid="Base_Column_List" /> from dept where id = #{id,jdbcType=INTEGER} </select>
我們可以看到user通過association中的dept_id關聯了dept,查詢user後,比如查詢到4個user,那麼會執行4次查詢dept;
測試
List<User> list = userMapper.selectByExample(null);
列印jdbc log我們能看到,查詢到4個user,然後執行了4次查詢dept
1+n帶來的問題
查詢主資料,是1次查詢,查詢出n條記錄;根據這n條主記錄,查詢從記錄,共需要n次,所以叫資料庫1+n問題;這樣會帶來效能問題,比如,查詢到的n條記錄,我可能只用到其中1條,但是也執行了n次從記錄查詢,這是不合理的。為了解決這個問題,出現了懶載入
<association property="dept" column="dept_id" fetchType="lazy" select="testmaven.mapper.DeptMapper.selectByPrimaryKey" ></association>
我們再做測試
List<User> list = userMapper.selectByExample(null); User u = list.get(0); System.out.println(u.getClass()); System.out.println(u.getName());
jdbc log
懶載入 減少了效能消耗,一定程度上緩解了1+n帶來的效能問題
總結
1+n問題是什麼?應該怎樣解決?
1+n是執行一次查詢獲取n條主資料後,由於關聯引起的執行n次查詢從資料;它帶來了效能問題;
一般來說,通過懶載入 可以部分緩解1+n帶來的效能問題