NHibernate可以配置为不为每个查询打开一个新的MySQL连接吗?

时间:2017-05-10 19:01:15

标签: mysql asp.net-web-api nhibernate

我们使用Asp.net Web API构建了一个Web服务。我们使用NHibernate作为连接MySQL数据库的ORM。

我们有几种控制器方法可以执行大量(1,000-3,000)相对便宜的查询。

我们正在寻求提高这些控制器方法的性能,几乎所有的时间都花在了NHibernate查询上,这就是我们关注的重点。

从中期来看,解决方案就像减少查询数量(可能通过减少更大的查询)和/或并行化查询(这需要一些工作,因为NHibernate没有异步api,会话是单一的这样的事情。

从短期来看,我们正在考虑提高绩效而不接受任何一个大型项目。

我们已经完成了一些性能分析,并且惊讶地发现每次查询(超过一半)的大部分时间都花在打开与MySQL的连接上。

似乎NHibernate为每个查询打开了一个与MySQL的新连接,并且每次打开连接时,MySqlConnection.Open()都会对数据库进行两次往返(即使连接来自池)。 / p>

以下是我们的一个效果配置文件的屏幕截图,您可以在其中看到以下两点:

Performance profile

我们想知道这是否是预期的,或者我们是否遗漏了诸如NHibernate的错误配置/误用或者在MySqlConnection.Open()中消除两次往返数据库的方法。

我做了一些额外的挖掘,发现了一些有趣的东西:

如果我们将.SetProperty(Environment.ReleaseConnections, "on_close")添加到NHibernate配置中,则不再调用Open(),并且执行查询所需的时间会下降超过40%。

但似乎这不是推荐的设置:http://nhibernate.info/doc/nhibernate-reference/transactions.html#transactions-connection-release

基于我希望获得相同行为的文档(没有额外的Open()调用)如果我将读取包装在单个NHibernate事务中但我无法使其工作。这就是我在控制器方法中所做的:

using (var session = _sessionFactory.OpenSession()) {
    using (var transaction = session.BeginTransaction()) {

        // controller code

        transaction.Commit();
    }
}

有关如何使用NHibernate的推荐配置获得相同行为的任何想法?

在进一步深入研究之后,我的测试实现中出现了一个错误,在使用事务修复之后,消除了对预期的Open()的额外调用。

1 个答案:

答案 0 :(得分:1)

  

并行化查询(自NHibernate以来需要一些工作   没有异步api,会话是单线程的)和   这样的事情。

您可以使用NHibernate Futures

推迟查询的执行

以下代码(摘自reference文章)将执行单个查询,尽管检索到2个值,

String s = "-i" + " " + mVideoUri.toString().replace("file:///", "") + " -filter_complex [1:v][0:v]scale2ref=iw:ih[ovr][base];[ovr]colorchannelmixer=aa=0.7[ovrl];[base][ovrl]overlay[v] -ss -to -map [v]" + directoryToStore + "/" + FileName + mp4;

String[] arguments = s.split(" ");

ExecuteFFMPEG(arguments);

您还可以使用NHibernate Batching来减少查询次数