查询和提交的会议上生活需要更长的时间(Queries and Commits take longer

2019-09-28 10:52发布

我用流利的NHibernate的数据导入到SQL Server数据库。

我用自动映射在我的实体(这完美地工作)

Fluently.Configure(nhibernateConfig_)
    .Mappings(map_ => map_.AutoMappings.Add(AutoMap
    .AssemblyOf<EntityMapping>(new AutomapConfiguration())
    .UseOverridesFromAssemblyOf<EntityMapping>()
    .Conventions.AddFromAssemblyOf<EntityMapping>()));

并使用QueryOver从数据库中获取数据

public AttributeTranslation GetOrCreateAttributeTranslation(Attribute attribute_, string language_)
{
    AttributeTranslation translation = _session
        .QueryOver<AttributeTranslation>()
        .And(trans_ => trans_.Attribute == attribute_)
        .And(trans_ => trans_.Language == language_)
        .SingleOrDefault();

    if (translation == null) {
        translation = new AttributeTranslation() {
            Language = language_,
            Attribute = attribute_
        };
        Save(translation);
    }

    return translation;
}

不幸的是,我处理我的输入,每个查询阅读和会话的进行每个提交的事务需要更长的时间和更长的时间。

// Surrounded in several for loops that process the input
using (ITransaction transaction = _repo.BeginTransaction()) {
    Stopwatch transGetWatch = Stopwatch.StartNew();
    AttributeTranslation translation = _repo.GetOrCreateAttributeTranslation(attribute, lang.Key);
    transGetWatch.Stop();
    translation.DisplayName = value;
    _repo.Save(translation);

    Stopwatch commitWatch = Stopwatch.StartNew();
    transaction.Commit();
    commitWatch.Stop();

    Console.Write("\rGetTrans[{0}] Commit[{1}]                    ",
        transGetWatch.ElapsedMilliseconds,
        commitWatch.ElapsedMilliseconds);
}

我试图切换希洛的ID生成,但无济于事。

public class AttributeTranslationMapOverride : IAutoMappingOverride<AttributeTranslation>
{
    public void Override(AutoMapping<AttributeTranslation> map_)
    {
        map_.Id(attr_ => attr_.Id).GeneratedBy.HiLo("attributeTranslationMaxLo");
    }
}

查询并承诺以每待命3-4毫秒开始时和结束时某处大约80到100结束。

我不一定需要使整机性能下降,我只是希望它稳定在每次通话的最初3至4毫秒。

什么可能是怎么回事呢?

Answer 1:

作为一个ORM,NHibernate的并不完全适合于批处理工作,因此你会遇到麻烦。 但它有一些功能使用它的批处理工作反正帮助。

由于涉嫌大卫·奥斯本 ,会话一级缓存可以使用时长过大ISession批量的工作,如您的数据导入。

有许多可以选择的解决方案:

  • 清除会话( ISession.Clear ),大卫·奥斯本的建议和推荐的参考文档 。 如果每行数据从来没有在共同与以前行的引用一些数据,每一行后结算就不会受到伤害。 做每50个或100行应该足以避免日益增长的会话一级缓存的太大影响性能。 根据您的调查结果进行调整。
  • 会议很便宜。 您可能,而不是清算,请换用新的。 (但要避免这样做,在每一行,它不是完全免费的。)
  • 考虑使用无状态会话 ( ISessionFactory.OpenStatelessSession() 它们可以是更适合于一些批处理。

笔记:

您当前的实现看起来节省每笔交易只有一个实体。 如果你可以节省一堆相同的类的实体,而不是,您可能会受益于配料 (至少SQL服务器),提高性能。 这也将减少连接释放个数/重新获取,因为默认情况下,每次交易后的SQL连接被释放。



文章来源: Queries and Commits take longer as the session lives on