接手一项目,数据层是Hibernate,运行很慢,单步跟踪了一下,
连接数据库,hibernate打印出来的log中,同样的select语句有几十条?是不是表明访问了几十次DB?例如:
Hibernate: select....... from a where ......
sql语句是写在*.hbm.xml中的,使用session.getNamedQuery(params)来获取
连接数据库,hibernate打印出来的log中,同样的select语句有几十条?是不是表明访问了几十次DB?例如:
Hibernate: select....... from a where ......
sql语句是写在*.hbm.xml中的,使用session.getNamedQuery(params)来获取
如果是我们自己配的一个复杂的sql的话 那么 在实际中 她是有可能 去查询 多次数据库的
<class name="history">
<id name="id" column="id" type="java.lang.String" length="32">
<generator class="uuid.hex">
</generator>
</id> <property name="code" type="java.lang.String" update="true"
insert="true" column="code" length="50" /> <property name="falg" type="java.lang.String" update="true"
insert="true" column="falg" length="1" /> <property name="name" type="java.lang.String" update="true"
insert="true" column="name" length="50" /> <map name="privateQueries" table="operatorsHistory" lazy="false"
sort="unsorted" cascade="all"> <key column="history"></key> <index column="id" type="java.lang.String" length="64" /> <many-to-many class="Operator"
column="operator" outer-join="auto" /> </map> </class> <query name="fromHistory"><![CDATA[
from History as i where i.falg='0'
]]></query>
<query name="fromHistoryWhereCode"><![CDATA[
from History as i where i.code=?
]]></query></hibernate-mapping>
<map name="privateQueries" table="operatorsHistory" lazy="false"
sort="unsorted" cascade="all">lazy="false" 这句话代表 延迟加载开启 。privateQueries 明显是一个SET会产生N+1的问题在数据少的时候并没有问题但是 比如你数据很多由于是使用延迟加载技术而且还是false 的情况下每查询这个表 默认都会去加载这个SET所以就会出现N+1的问题 并且随着数据的增长
、
这个N会越来越大。。建议先把他改成TRUE 去查查哪里使用了这个SET 去手动写HQL 加载一下吧不然耗费效率绝对不是你能忍受的先改成TRUE 跟踪一下SQL 是否减少了很多就知道是否是他的问题
根据log显示 History 表查询了一次,但是map中的operatorsHistory被查询了十几次?
这是怎么回事了?
<map name="privateQueries"......像上面history表的xml中有map,就会访问map中的表几十次甚至上百次,但对history表只会访问一次(这正是需要实现的),
另外试了几张表都是这样,如果除去map,log已经显示很少了,
但对hibernate不是很熟悉,不知道在xml中除去map属性是否合适?望大家指点了?
sort="unsorted" cascade="all">lazy="false" 表示延迟加载开启将他变为true 就可以了如果在外面有调用 就会爆出 SESSION CLOSE 的错误的在那里 手动写SQL 加载一下MAP 就可以了