Lock ActiveRecord / NHibernate optimization
I have the following structure: a message (message table) can have multiple fields (fields table) and each field can have multiple subfields (stored in the same "fields" table with the only difference that the fields have no values in Column "ParentField"). The subfields can have subheadings, etc., but that doesn't matter.
When I get 10 messages, each with 10 fields and each field has 20 subfields, I can see from the log file that NHibernate is generating 2000 SQL calls. Is there a way to optimize this?
Thank!
Here is one of 2000 SQL statements generated by NHibernate:
SELECT fieldresul0_.MessageResults_ID as MessageR6___2_,
fieldresul0_.ID as ID2_,
fieldresul0_.ID as ID5_1_,
fieldresul0_.Field_ID as Field2_5_1_,
fieldresul0_.Name as Name5_1_,
fieldresul0_.Value as Value5_1_,
fieldresul0_.MessagePosition as MessageP5_5_1_,
fieldresul0_.MessageResults_ID as MessageR6_5_1_,
fieldresul0_.ParentField_ID as ParentFi7_5_1_,
fieldresul1_.ID as ID5_0_,
fieldresul1_.Field_ID as Field2_5_0_,
fieldresul1_.Name as Name5_0_,
fieldresul1_.Value as Value5_0_,
fieldresul1_.MessagePosition as MessageP5_5_0_,
fieldresul1_.MessageResults_ID as MessageR6_5_0_,
fieldresul1_.ParentField_ID as ParentFi7_5_0_
FROM FieldResults fieldresul0_
LEFT OUTER JOIN FieldResults fieldresul1_
ON fieldresul0_.ParentField_ID=fieldresul1_.ID
WHERE fieldresul0_.MessageResults_ID=@p0
ORDER BY fieldresul0_.MessagePosition
Here is the mapping file that ActiveRecord generates:
<?xml version="1.0" encoding="utf-16"?>
<hibernate-mapping auto-import="true" default-lazy="false" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
<class name="FieldResult, Data" table="FieldResults">
<id name="ID" access="property" column="ID" type="Int32" unsaved-value="0">
<generator class="native">
<param name="sequence">FieldResults_ID</param>
</generator>
</id>
<property name="FieldID" access="property" type="String">
<column name="Field_ID"/>
</property>
<property name="Name" access="property" type="String">
<column name="Name"/>
</property>
<property name="DisplayValue" access="property" type="String">
<column name="Value"/>
</property>
<property name="MessagePosition" access="property" type="Int32">
<column name="MessagePosition"/>
</property>
<many-to-one name="ParentMessage" access="property" class="MessageResult, Data" column="MessageResults_ID" />
<many-to-one name="ParentField" access="property" class="FieldResult, Data" column="ParentField_ID" />
<bag name="Children" access="property" table="FieldResults" lazy="false" cascade="all" order-by="Field_ID">
<key column="ParentField_ID" />
<one-to-many class="FieldResult, Data" />
</bag>
</class>
</hibernate-mapping>`
source to share
there is a way to help nhibernate do more efficient joins. explicitly tell the query processor to include lookup tables using "join fetch" and get your results through HQL and Session.CreateQuery ()
from FieldRestults fr
left join fetch fr.ParentMessage
left join fetch fr.ParentField
Package optimization is another issue that I am currently investigating.
source to share