NHibernate的 - 第一个查询慢得令人痛苦(NHibernate - first query

2019-10-18 03:18发布

含有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
}

为什么第一次查询时间这么长? 有没有一种方法,以加快步伐?

Answer 1:

很可能是缓存。 你有没有索引可以与查询的帮助,所以全表扫描得到任何答案的唯一途径。 第一个会,或者由DB(可能不会为表扫描),但肯定的是O / S将缓存全部或部分磁盘页面填满缓冲区和高速缓存。 第二个查询将受益于在一定程度上被缓存的页面。

克雷格的建议也对缓存和启动一个微妙的自旋 - 你第一次做任何事情往往招致位的一击,你需要找出什么。 在Web应用程序之前,应用程序接受请求,你可以做一点启动的。 如果这是更大的一批东西,你不能伪装的热身,那么你可能只需要忍受它或沟NHibernate的。

以他的意见及衡量这是怎么回事在休眠了。



Answer 2:

还有平时开销使得在这种情况下,你不会因为连接池的其他查询看到一个数据库的连接。 根据你那里的时机,我会说这是你所看到的问题。

此外,请确保您只让你的会话工厂只有一次,缓存,然后打开从该会话。 我不认为你正在运行成根据您的时间,但有一个足够小的配置可能是这一点。



Answer 3:

可能的解决方法1:
我已经在几年前看的性能问题,我发现这个问题是由NHibernate的使用XML序列化器的初始化。 我报一个错误,它在吉拉修复: https://nhibernate.jira.com/browse/NH-2958

试试你的NHibernate的来源我的修补程序,看看问题是否得到解决。 这个问题将根据JIRA系统是固定在NHibernate中的下一个版本。

可能的解决方法2:
如果解决方案1不工作,尝试在你的映射每个classmapping设置动态更新和动态插入到真。 NHibernate的编译你的映射时创建了所有可能出现的问题。



文章来源: NHibernate - first query is painfully slow