우리는 일대일 대응 문제, NHProf 선택 N + 1을 직면하고 있습니다. 경고, FetchMode.Join을 사용하기위한 기준 변경 중 N + 1 문제가 해결되지 않았습니다. 다음은 세부 사항입니다.일대일 연결 문제, NHProf 선택 N + 1 경고 표시, FetchMode.Join을 사용하지 않는 기준 변경 N + 1 문제 해결 안 함?
소프트웨어 버전 정보 : NH 버전 : 1.2 .NET 버전 : 3.5 DB : 오라클 11g 2 수준 캐시 : 사용
HBM 파일 및 클래스 개체.
설명 '샘플'엔티티는 0 또는 1 개의 '연관' 엔티티를 포함 할 수 있습니다. 'Association'엔티티에는 'Sample'엔티티의 외래 키 제약 조건이 있습니다.
Sample.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHSample" namespace="NHSample">
<class name="Sample" table="SAMPLE" proxy="Sample"
polymorphism="explicit" >
<id name="Id" type="Decimal" unsaved-value="-1">
<column name="SA_ID" sql-type="NUMBER" not-null="true"
unique="true"/>
<generator class="sequence">
<param name="sequence">SA_ID_SEQ</param>
</generator>
</id>
<property name="SampleName" type="String">
<column name="SAMPLE_NAME" length="100" sql-type="VARCHAR2" not-
null="false"/>
</property>
<one-to-one name="Association" class="Association" property-
ref="SampleAssociated" cascade="all-delete-orphan"/>
</class>
</hibernate-mapping>
Sample.cs
namespace NHSample
{
public class Sample
{
public virtual decimal Id
{
get ;
set ;
}
public virtual string SampleName
{
get ;
set ;
}
public virtual Association Association
{
get ;
set ;
}
}
}
Association.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHSample" namespace="NHSample">
<class name="Association" table="ASSOCIATION">
<id name="Id" type="Decimal" unsaved-value="-1">
<column name="AS_ID" sql-type="NUMBER" not-null="true"
unique="true"/>
<generator class="sequence">
<param name="sequence">AS_ID_SEQ</param>
</generator>
</id>
<property name="AssociationName" type="String">
<column name="ASSOCIATION_NAME" length="100" sql-type="VARCHAR2" not-
null="false"/>
</property>
<many-to-one name="SampleAssociated" class="Sample">
<column name="SA_ID" sql-type="NUMBER" not-null="true"/>
</many-to-one>
</class>
</hibernate-mapping>
Association.cs
namespace NHSample
{
public class Association
{
public virtual decimal Id
{
get ;
set ;
}
public virtual string AssociationName
{
get ;
set ;
}
public virtual Sample SampleAssociated
{
get ;
set ;
}
}
}
WITHOUT의 fetchMode 7백45경1천5백15조5백36억9천1백36만3천2백10
기준 = 샘플 엔티티에 액세스하기 위해 사용 조인 Criteria.List()를 실행 한 경우
class Program
{
static void Main(string[] args)
{
using (ISession session = SessionFactory.OpenSession())
{
var electedIds = new List<decimal>() { 1, 2, 3 };
ICriteria criteria =
session.CreateCriteria(typeof(Sample));
criteria.Add(Expression.In("Id", electedIds));
var list = criteria.List();
}
Console.ReadKey();
}
}
는 NHProf는 N + 1 개 경보를 보였다. 다음은 NHProf에서 보여준 SQL 구문입니다.
- 문 # 1
SELECT this_.SA_ID as SA1_0_1_,
this_.SAMPLE_NAME as SAMPLE2_0_1_,
associatio2_.AS_ID as AS1_1_0_,
associatio2_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio2_.SA_ID as SA3_1_0_
FROM SAMPLE this_
left outer join ASSOCIATION associatio2_
on this_.SA_ID = associatio2_.SA_ID
WHERE this_.SA_ID in (1 /* :p0 */,2 /* :p1 */,3 /* :p2 */)
- 문 # 2
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 1 /* :p0 */
- 문 # 3
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 2 /* :p0 */
- 문 # 4
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 3 /* :p0 */
FETCHMODE.Join를 사용 cirteria 수정
사용 NHProf 웹 사이트 제안 : 여전히 N + 1 경고를 표시하고 다음
class Program
{
static void Main(string[] args)
{
using (ISession session = SessionFactory.OpenSession())
{
var electedIds = new List<decimal>() { 1, 2, 3 };
ICriteria criteria =
session.CreateCriteria(typeof(Sample));
criteria.SetFetchMode("Association", FetchMode.Join);
criteria.Add(Expression.In("Id", electedIds));
var listByIds = criteria.List();
}
Console.ReadKey();
}
}
NHProf는 SQL 쿼리입니다.
- 문 # 1
SELECT this_.SA_ID as SA1_0_1_,
this_.SAMPLE_NAME as SAMPLE2_0_1_,
associatio2_.AS_ID as AS1_1_0_,
associatio2_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio2_.SA_ID as SA3_1_0_
FROM SAMPLE this_
left outer join ASSOCIATION associatio2_
on this_.SA_ID = associatio2_.SA_ID
WHERE this_.SA_ID in (1 /* :p0 */,2 /* :p1 */,3 /* :p2 */)
- 문 # 2
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 1 /* :p0 */
- 문 # 3
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 2 /* :p0 */
- 문 # 4
SELECT associatio0_.AS_ID as AS1_1_0_,
associatio0_.ASSOCIATION_NAME as ASSOCIAT2_1_0_,
associatio0_.SA_ID as SA3_1_0_
FROM ASSOCIATION associatio0_
WHERE associatio0_.SA_ID = 3 /* :p0 */
이 시나리오에서이 추가 SQL 구문과 N + 1 문제를 해결하는 방법에 대한 의견.
감사합니다.
현재 JIRA 링크 : https://nhibernate.jira.com/browse/NH-2534 –