【问题标题】:Avoiding SELECT+1 when working with discriminators使用鉴别器时避免 SELECT+1
【发布时间】:2012-02-07 01:24:00
【问题描述】:

我正在使用鉴别器来处理项目状态。我正在使用 NHibernate Profiler 并注意到我的应用程序在选择我的状态时非常疯狂。我总共有 8 个状态,NHibernate 一直这样查询:

SELECT state0_.State_id         as State1_10_0_,
       state0_.Name             as Name10_0_
FROM   States state0_
WHERE  state0_.State_id = **3** /* @p0 */

触发此 SELECT+1 的原因是当我选择状态等于 1、2、3、4 或 5 的所有项目时。这将为我的项目发出一个查询,并且为每个状态发出 5 个查询。因为我经常查询项目(有状态),所以我执行了大量的查询。

现在,看看探查器,我不确定这是否是一个很大的问题,因为我查询的第一个状态需要 6 毫秒来查询和 6 毫秒来实现。所有其他状态显示为查询时间为 0 毫秒,具体化时间为 0 毫秒。 NHibernate Profiler 仍然将此显示为臭名昭著的 SELECT+1 问题。

从我的聚合根映射中,我有:

        References(x => x.State)
            .Not.Nullable()
            .Not.LazyLoad();

对于我的状态鉴别器映射,我有:

        Id(x => x.Id, "State_id").GeneratedBy.Assigned();
        Map(x => x.Name).Not.Nullable();

        DiscriminateSubClassesOnColumn("State_id");

关于鉴别器有什么我不理解的地方吗?

这是导致问题的查询:

var items =
    session.QueryOver(() => itemAlias)
        .SelectList(x => x
                             .Select(xx => xx.Id).WithAlias(() => sentTo.Id)
                             .Select(xx => xx.State).WithAlias(() => sentTo.State)
                             .Select(xx => xx.Status).WithAlias(() => sentTo.Status)
        )
        .JoinAlias(() => itemAlias.State, () => stateAlias)
        .WhereRestrictionOn(() => stateAlias.Id).IsInG(filters)
        .Where(() => itemAlias.Status == Status.InProgress)
        .TransformUsing(Transformers.AliasToBean<SentToDto>())
        .List<SentToDto>();

解决方案

罪魁祸首是

.WhereRestrictionOn(() => stateAlias.Id).IsInG(filters)

要解决我的 SELECT+1 问题,我只需要通过鉴别器对象列表而不是单个 id 进行查询。

.Where(() => itemAlias.State.IsIn(new []{State.FooState, State.BarState}))

【问题讨论】:

  • 能否提供您的查询码?

标签: nhibernate fluent-nhibernate


【解决方案1】:

听起来您自己渴望加载状态,所以您的第一个查询类似于:

SELECT * FROM Items where StateID IN (1,2,3,4,5)

然后每个州有五个查询:

SELECT Name FROM State WHERE StateID = 1
SELECT Name FROM State WHERE StateID = 2
....

这样做是为了急切加载状态的名称,因此为避免这种情况,您应该在第一个查询中指定从“项目”到“状态”的连接,以便在那里获得名称,否则设置状态对象如果您不需要结果中的标识符以外的其他信息,则延迟加载。

【讨论】:

    猜你喜欢
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多