首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

n+1有关问题

2012-09-05 
n+1问题http://hi.baidu.com/victorlin23/blog/item/8b7a3382670cd9b16d811963.htmlFind()方法下FetchType

n+1问题
http://hi.baidu.com/victorlin23/blog/item/8b7a3382670cd9b16d811963.html

Find()方法下FetchType.LAZY、FetchType.EAGER、@Fetch(FetchMode.JOIN)的区别2010-08-27 16:13结论:1.使用例如:@ManyToOne(fetch = FetchType.LAZY)将会产生N+1的问题。      2.使用:@ManyToOne(fetch = FetchType.EAGER)将会使用join查询,推断hibernate对eaer进行了优化并不会产生N+1的问题。       3.使用:@Fetch(FetchMode.JOIN)将和第2项描述的执行效果和步骤是一样的,都是使用join 可以得出官方文档:Hibernate_Annotations.pdf第62页描述的Table 2.3. Lazy and fetch options equivalent是正确的。完全等价。hibernate重载了EJG的Fetch注解                                      一、@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "SERVICE_ID", referencedColumnName = "ID")public SystemServiceInfo getSysService() {   return sysService;}使用Lazy查询,由于需要立即访问触发了数据库查询。这个时候出现了N+1的问题:    select        count(*) as y0_     from        at_t_client_and_service this_     inner join        AT_T_CLIENT_INFO clientinfo1_             on this_.CLIENT_ID=clientinfo1_.id     where        (            1=1        )         and (            clientinfo1_.id = ?        )Hibernate:     select        *     from        ( select            this_.id as id56_1_,            this_.URL as URL56_1_,            this_.CLIENT_ID as CLIENT15_56_1_,            this_.CREATE_DATE as CREATE3_56_1_,            this_.SERVICE_ID as SERVICE16_56_1_,            this_.NAME_SPACE_URL as NAME4_56_1_,            this_.LOCAL_PART_SERVICE as LOCAL5_56_1_,            this_.LOCAL_PART_PORT as LOCAL6_56_1_,            this_.PERIOD_BEGIN_DATE as PERIOD7_56_1_,            this_.PERIOD_END_DATE as PERIOD8_56_1_,            this_.FTP_FLAG as FTP9_56_1_,            this_.FTP_RELATIVE_FLAG as FTP10_56_1_,            this_.FTP_PATH as FTP11_56_1_,            this_.FTP_PORT as FTP12_56_1_,            this_.FTP_USER as FTP13_56_1_,            this_.FTP_PASSWORD as FTP14_56_1_,            clientinfo1_.id as id63_0_,            clientinfo1_.CLIENT_ID as CLIENT2_63_0_,            clientinfo1_.CLIENT_IP as CLIENT3_63_0_,            clientinfo1_.CLIENT_NAME as CLIENT4_63_0_,            clientinfo1_.REGEST_TIME as REGEST5_63_0_,            clientinfo1_.REMARK as REMARK63_0_         from            at_t_client_and_service this_         inner join            AT_T_CLIENT_INFO clientinfo1_                 on this_.CLIENT_ID=clientinfo1_.id         where            (                1=1            )             and (                clientinfo1_.id = ?            ) )     where        rownum <= ?Hibernate:     select        systemserv0_.id as id28_0_,        systemserv0_.COMM as COMM28_0_,        systemserv0_.SERVICE_NAME as SERVICE3_28_0_,        systemserv0_.CREATE_DATE as CREATE4_28_0_     from        AT_T_SERVICE systemserv0_     where        systemserv0_.id=?Hibernate:     select        systemserv0_.id as id28_0_,        systemserv0_.COMM as COMM28_0_,        systemserv0_.SERVICE_NAME as SERVICE3_28_0_,        systemserv0_.CREATE_DATE as CREATE4_28_0_     from        AT_T_SERVICE systemserv0_     where        systemserv0_.id=?二、@ManyToOne(fetch = FetchType.EAGER)@JoinColumn(name = "SERVICE_ID", referencedColumnName = "ID")public SystemServiceInfo getSysService() {   return sysService;}并未出现N+1的问题Hibernate:     select        count(*) as y0_     from        at_t_client_and_service this_     inner join        AT_T_CLIENT_INFO clientinfo1_             on this_.CLIENT_ID=clientinfo1_.id     where        (            1=1        )         and (            clientinfo1_.id = ?        )Hibernate:     select        *     from        ( select            this_.id as id61_2_,            this_.URL as URL61_2_,            this_.CLIENT_ID as CLIENT15_61_2_,            this_.CREATE_DATE as CREATE3_61_2_,            this_.SERVICE_ID as SERVICE16_61_2_,            this_.NAME_SPACE_URL as NAME4_61_2_,            this_.LOCAL_PART_SERVICE as LOCAL5_61_2_,            this_.LOCAL_PART_PORT as LOCAL6_61_2_,            this_.PERIOD_BEGIN_DATE as PERIOD7_61_2_,            this_.PERIOD_END_DATE as PERIOD8_61_2_,            this_.FTP_FLAG as FTP9_61_2_,            this_.FTP_RELATIVE_FLAG as FTP10_61_2_,            this_.FTP_PATH as FTP11_61_2_,            this_.FTP_PORT as FTP12_61_2_,            this_.FTP_USER as FTP13_61_2_,            this_.FTP_PASSWORD as FTP14_61_2_,            clientinfo1_.id as id63_0_,            clientinfo1_.CLIENT_ID as CLIENT2_63_0_,            clientinfo1_.CLIENT_IP as CLIENT3_63_0_,            clientinfo1_.CLIENT_NAME as CLIENT4_63_0_,            clientinfo1_.REGEST_TIME as REGEST5_63_0_,            clientinfo1_.REMARK as REMARK63_0_,            systemserv4_.id as id29_1_,            systemserv4_.COMM as COMM29_1_,            systemserv4_.SERVICE_NAME as SERVICE3_29_1_,            systemserv4_.CREATE_DATE as CREATE4_29_1_         from            at_t_client_and_service this_         inner join            AT_T_CLIENT_INFO clientinfo1_                 on this_.CLIENT_ID=clientinfo1_.id         left outer join            AT_T_SERVICE systemserv4_                 on this_.SERVICE_ID=systemserv4_.id         where            (                1=1            )             and (                clientinfo1_.id = ?            ) )     where        rownum <= ?三、 @ManyToOne@Fetch(FetchMode.JOIN)@JoinColumn(name = "CLIENT_ID", referencedColumnName = "ID")public ClientInfo getClientInfo() {   return clientInfo;}未出现N+1的问题。而且和第二种配置的效果完全一样,证实了hibernate做eager时进行了优化,使用了ourtjoin,并不会产生N+1问题。Hibernate:     select        count(*) as y0_     from        at_t_client_and_service this_     inner join        AT_T_CLIENT_INFO clientinfo1_             on this_.CLIENT_ID=clientinfo1_.id     where        (            1=1        )         and (            clientinfo1_.id = ?        )Hibernate:     select        *     from        ( select            this_.id as id35_2_,            this_.URL as URL35_2_,            this_.CLIENT_ID as CLIENT15_35_2_,            this_.CREATE_DATE as CREATE3_35_2_,            this_.SERVICE_ID as SERVICE16_35_2_,            this_.NAME_SPACE_URL as NAME4_35_2_,            this_.LOCAL_PART_SERVICE as LOCAL5_35_2_,            this_.LOCAL_PART_PORT as LOCAL6_35_2_,            this_.PERIOD_BEGIN_DATE as PERIOD7_35_2_,            this_.PERIOD_END_DATE as PERIOD8_35_2_,            this_.FTP_FLAG as FTP9_35_2_,            this_.FTP_RELATIVE_FLAG as FTP10_35_2_,            this_.FTP_PATH as FTP11_35_2_,            this_.FTP_PORT as FTP12_35_2_,            this_.FTP_USER as FTP13_35_2_,            this_.FTP_PASSWORD as FTP14_35_2_,            clientinfo1_.id as id47_0_,            clientinfo1_.CLIENT_ID as CLIENT2_47_0_,            clientinfo1_.CLIENT_IP as CLIENT3_47_0_,            clientinfo1_.CLIENT_NAME as CLIENT4_47_0_,            clientinfo1_.REGEST_TIME as REGEST5_47_0_,            clientinfo1_.REMARK as REMARK47_0_,            systemserv4_.id as id58_1_,            systemserv4_.COMM as COMM58_1_,            systemserv4_.SERVICE_NAME as SERVICE3_58_1_,            systemserv4_.CREATE_DATE as CREATE4_58_1_         from            at_t_client_and_service this_         inner join            AT_T_CLIENT_INFO clientinfo1_                 on this_.CLIENT_ID=clientinfo1_.id         left outer join            AT_T_SERVICE systemserv4_                 on this_.SERVICE_ID=systemserv4_.id         where            (                1=1            )             and (                clientinfo1_.id = ?            ) )     where        rownum <= ?参考官方文档:Hibernate_Annotations.pdf   P62。The Hibernate annotations overrides the EJB3 fetching options 

热点排行