NHibernate - 第一个查询非常缓慢

时间:2013-05-13 22:45:29

标签: c# postgresql nhibernate fluent-nhibernate

包含10000行的数据库表(PostgreSQL):

CREATE TABLE test
(
  id bigserial NOT NULL,
  text text,
  CONSTRAINT test_pkey PRIMARY KEY (id)
)

类:

public class Test
{
    public virtual int ID { get; set; }
    public virtual string Text { get; set; }
}

public class TestMap : ClassMap<Test>
{
    public TestMap()
    {
        Table("test");
        Id(x => x.ID, "id");
        Map(x => x.Text, "text");
    }
}

以下是我查询数据库的方法:

using (ISession session = SessionBuilder.OpenSession())
{
    Stopwatch s = new Stopwatch();

    s.Start();
    var result = session.QueryOver<Test>().Where(test => test.Text == "aaa").List();
    s.Stop();
    Console.WriteLine(s.ElapsedMilliseconds); // >150ms

    s.Restart();
    var result2 = session.QueryOver<Test>().Where(test => test.Text == "bbb").List();
    s.Stop();
    Console.WriteLine(s.ElapsedMilliseconds); // ~4ms
}

为什么第一个查询需要这么长时间?有没有办法加快速度?

3 个答案:

答案 0 :(得分:1)

很可能是缓存。您没有可以帮助查询的索引,因此全表扫描是获得答案的唯一方法。第一个将填充缓冲区和缓存,由DB(可能赢得表扫描)但当然O / S将缓存所有或一些磁盘页。第二个查询将受益于某些级别缓存的页面。

克雷格的建议也是对缓存和微软的微妙转变。启动 - 你第一次做任何事情往往会引起一些打击,你需要找出什么。在网络应用程序中,您可以在应用程序接受请求之前进行一些启动。如果这更像是一件你无法掩饰热身的批量事情,那么你可能只需忍受它或者放弃nHibernate。

接受他的建议&amp;衡量Hibernate中正在发生的事情。

答案 1 :(得分:1)

与数据库建立连接通常会产生开销,在这种情况下,由于连接池,您将看不到其他查询。根据你在那里的时间,我会说这是你看到的问题。

此外,请确保您只将会话工厂设置为一次并缓存它,然后从中打开会话。根据你的时间安排我不认为你会遇到这种情况,但是如果配置足够小,也可能就是这样。

答案 2 :(得分:0)

可能的解决方案1:
几年前我一直在关注性能问题,我发现的问题是NHibernate使用的XML序列化程序的初始化。我在Jira上报告了一个错误并修复了它: https://nhibernate.jira.com/browse/NH-2958

尝试修复你的nhibernate源代码并查看问题是否已解决。根据jira系统,该问题将在下一版本的nhibernate中修复。

可能的解决方案2:
如果解决方案1不起作用,请尝试在每个类映射的映射中将动态更新和动态插入设置为true。 NHibernate在编译映射时会创建所有可能的查询。