【问题标题】:Castle ActiveRecord / NHibernate optimizationCastle ActiveRecord / NHibernate 优化
【发布时间】:2008-12-30 20:10:02
【问题描述】:

我的结构如下:消息(消息表)可能有多个字段(字段表),每个字段可能有多个子字段(存储在同一个“字段”表中,唯一的区别是字段中没有值“父字段”列)。子字段可能有子子字段等,但这并不重要。

当我检索 10 条消息,每条消息有 10 个字段,每个字段有 20 个子字段时,我可以从日志文件中看到 NHibernate 生成了 2000 个 SQL 调用。 有没有办法优化它?

谢谢!

这是 NHibernate 生成的 2000 条 SQL 语句之一:

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

这是 ActiveRecord 生成的映射文件:

<?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>`   

【问题讨论】:

    标签: nhibernate castle-activerecord


    【解决方案1】:

    我猜这是一个选择 n+1 的问题。您是否尝试过预先加载或自定义 HQL 查询?如果你还没有,我会发布一些示例 HQL 来解决这个问题

    【讨论】:

      【解决方案2】:

      有一种方法可以帮助 nhibernate 执行一些更有效的连接。明确告诉查询处理器包含带有“join fetch”的查找表,并通过 HQL 和 Session.CreateQuery() 获取结果

      from FieldRestults fr 
      left join fetch fr.ParentMessage 
      left join fetch fr.ParentField
      

      在我目前正在调查的另一个问题中优化包。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 2011-09-02
        相关资源
        最近更新 更多