0

我是 nHibernate 的新手,并且从一个简单的选择查询中得到了一些非常慢的结果。也许我错过了一些明显的东西。情况如下:

  • 我正在使用流利的 nHibernate。
  • 我正在查询一个 oracle 数据库(10g),我正在尝试返回一个人对象。
  • 每条记录大约需要 16 秒!

这是我流畅的 nHibernate 代码:

public class Person
{
    public virtual string PersonId { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Schema("MyTestDB");
        Table("Person");
        Id(i => i.PersonId);
        Map(i => i.FirstName);
        Map(i => i.LastName);
    }
}

这是假设检索实际数据的代码:

var sessionFactory = Fluently.Configure().Database(OracleClientConfiguration.Oracle10.ConnectionString(@"User Id=tester;Password=tester99!;Data Source=MyTestDB;").ShowSql()).Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())).BuildSessionFactory();                   

    using (var session = sessionFactory.OpenSession())
    {           
        using (session.BeginTransaction())
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();

            var person = session.QueryOver<Person>()
                                .Where(p => p.PersonId == "1").SingleOrDefault();

            stopWatch.Stop();

            var ts = stopWatch.Elapsed;
            var time = string.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds/10);

            Console.WriteLine("Retrieved object: Person, Id: {0}, First Name: {1}, Last Name: {2} in [{3}]", person.PersonId, person.FirstName, person.LastName, time);
        }
    }

PersonId 列已编入索引并且是主键。

到目前为止,我试图解决这个问题的尝试是使用 ADO.Net 运行 nHibernate 生成的相同 sql。查询运行得非常快(秒表的经过时间为 0)。

使用 plsql developer 在数据库上运行相同的查询给出了相同的快速结果。这表明我认为它不是查询也不是数据库。

我该如何进一步调试呢?nHibernate 分析器会帮助解决这个问题(我目前没有这个可用)?

有什么想法吗?

4

3 回答 3

1

首先,您应该尝试在整个程序执行过程中捕捉更多的时间点。您假设它是 NHibernate 组件,但没有更多难以证明的数据点,尤其是当您的初始测试返回 0 时。

其次,在您的 NHibernate 方案中,最大的成本是调用BuildSessionFactory(). NHibernate 被优化为具有廉价的会话构造,因此它希望您创建这个工厂一次并在程序的整个生命周期内重复使用它。如果您在此事件周围放置跟踪点,您可能会发现您的“费用”。

于 2012-06-27T06:46:05.083 回答
0

如果我不得不在这里大胆猜测,问题不在于 nhibernate 查询数据库我认为这是您构建 sessionFactory 和/或会话的初始成本,这就是您看到异常延迟的原因。

为什么不使用Jetbrains dotTrace并查看实际性能影响在哪里,如果它在运行查询或其他方面。只需运行一个采样查询,您就可以得到每个函数调用次数的准确时间。

PS:我与 jetbrains 没有任何关联,只是推荐该产品的快乐客户。

于 2012-06-27T06:11:27.970 回答
0

问题最终是我没有指定主键列的数据类型,结果是 varchar(非 unicode)。事实证明,您需要为非 unicode 列指定数据类型,因为 fluent 假定字符串映射到 uni 代码。

这是如何以流利的表示法设置自定义类型:

 Map(x=>x.PersonId).CustomType("AnsiString");
于 2012-09-04T04:16:47.673 回答