1

NHibernate를 처음 사용합니다. NHibernate 프로필러에서 내 쿼리를 테스트 할 때 Select N + 1 경고가 표시됩니다. 나는 나의 매핑이나 질의에 대해 내가 뭘 잘못하고 있는지 확신하지 못한다.NHibernate 선택 N + 1

기본적으로 헤더라는 표가 있는데 많은 세부 정보가 있습니다. 각각의 세부 사항에 대해 나는 Replay를 가지고있다. 즉

하나 Header-> 많은 상세 한 상세 -> 하나의 재생

검색어 :

var query = _session.QueryOver(() => headerAlias) 
        .Where(() => headerAlias.ScriptNumber == scriptId) 
        .And(() => headerAlias.ChannelCode == channelId) 
        .Future<ProgramHeader>(); 

내 매핑 :

public ProgramHeaderMap() 
{ 
    Table("S_IDB_M_PROG_HDR"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD"); 

    Map(x => x.ChannelCode).Column("CHCD"); 
    Map(x => x.ShowCode).Column("SHOWCD"); 
    Map(x => x.ShowStartTime).Column("ONAIRSTART"); 
    Map(x => x.ShowEndTime).Column("ONAIREND"); 
    Map(x => x.Presenters).Column("HOST"); 
    Map(x => x.Guests).Column("GUEST"); 
    Map(x => x.Planners).Column("PLANNER"); 
    Map(x => x.ModifiedTime).Column("UPDDATE"); 

    HasMany(x => x.Pal) 
      .AsBag() 
      .Inverse() 
      .KeyColumns.Add("PROGCD", "CHCD") 
      .Cascade.All() 
      .Not.LazyLoad(); 
} 

DetailMap :

public ProgramDetailMap() 
{ 
    Table("S_IDB_M_PROG_DTL"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD") 
     .KeyProperty(x => x.ProductNumber, "PRODCD") 
     .KeyProperty(x => x.ColorCode, "COLORCD") 
     .KeyProperty(x => x.SizeCode, "SIZECD"); 

    Map(x => x.PromoCode,"PCPARAM1"); 
    Map(x => x.EasyPayInstalments,"EZINST"); 
    Map(x => x.EasyPayFirstAmount,"EZAMT"); 
    Map(x => x.EasyPayNextAmount,"EZAMT2"); 
    Map(x => x.UpdatedDate).Column("UPDDATE"); 

    References(x => x.ProgramHeader) 
     .Columns("PROGCD", "CHCD") 
     .LazyLoad(); 

    References(x => x.Replay) 
     .Columns("PROGCD", "CHCD", "PRODCD", "COLORCD", "SIZECD") 
     .NotFound.Ignore(); 
} 

}

재생 :

public ProgramReplayMap() 
{ 
    Table("S_IDB_M_PROG_REPL"); 

    CompositeId() 
     .KeyProperty(x => x.ScriptNumber, "PROGCD") 
     .KeyProperty(x => x.ChannelCode, "CHCD") 
     .KeyProperty(x => x.ProductNumber, "PRODCD") 
     .KeyProperty(x => x.ColorCode, "COLORCD") 
     .KeyProperty(x => x.SizeCode, "SIZECD"); 

    Map(x => x.Price, "REC_PRICE"); 
    Map(x => x.Postage, "REC_POSTAGE"); 
    Map(x => x.UpdatedDate).Column("UPDDATE"); 
} 

이 쿼리에 대한 몇 가지 응답을 주셔서 감사합니다.

감사합니다.

+0

"SELECT N + 1"의 의미를 이해합니까? –

+0

조금. 어떤 객체의 집합이 있고 각 객체가 다른 객체, 즉 1 대 다수 관계의 집합을 가지고 있다고 가정 해보십시오. SELECT N + 1은 기본 객체에 대한 하나의 선택 쿼리이고 N은 컬렉션을 가져 오기위한 추가 선택입니다. 희망이 맞습니다 –

+0

내 매핑이 올바른지 알고 싶습니다. –

답변

0

원하는 것은 일괄 처리 가져 오기를 사용하는 것입니다. 설명서는 http://nhibernate.info/doc/nhibernate-reference/performance.html#performance-fetching-batch

FluentNHibernate에서 ClassMap 및 컬렉션 매핑의 .BatchSize() 메서드로 사용할 수 있습니다.

배치 가져 오기는 NHibernate가 같은 유형의 여러 관련 인스턴스를 한 번에 가져올 수 있음을 의미합니다. 예를 들어, 각각 B 인스턴스 중 하나에 액세스하자마자 B에 대한 지연 참조를 보유하고있는 A의 20 인스턴스를로드 한 경우 Hibernate는 하나의 쿼리를 사용하여 20 개의 B 인스턴스를 모두로드 할 수 있습니다. 만약 당신이 참조 된 B 인스턴스 중 하나에 접근한다면, 곧 다른 인스턴스에도 접근 할 것이고 동일한 쿼리를 사용하여 20 개의 인스턴스를로드하는 것은 너무 빨라서 우리가로드하는 것이 중요하지 않다는 가정이 있습니다 실제로 필요한 것은 아닙니다. (숫자 20은 배치 크기 설정을 사용하여 제어하는 ​​것입니다.)

관련 문제