NHibernate - 第一个查询真的很慢

时间:2015-08-26 14:44:25

标签: c# nhibernate castle-activerecord

我知道这里已经发布了类似的问题:NHibernate - first query is painfully slow。不幸的是,它没有提供有效的答案。

基本上,问题是第一个NHibernate查询需要大约1000毫秒才能运行。我可以通过使用纯SQL查询将滞后降低到600毫秒。我们正在使用Castle.ActiveRecord。

  • NHibernate版本:3.1.0.4000
  • Castle.ActiveRecord版本:3.0.0.0

查询很简单:通过用户名从DB获取用户对象。

return FindFirst(Expression.Eq("UserName", userName));

可以像这样创建表:

CREATE TABLE [dbo].[USER](
    [USER_ID] [int] NOT NULL,
    [COMPANY_ID] [int] NULL,
    [USER_NAME] [varchar](100) NOT NULL,
    [PASSWORD] [varchar](100) NOT NULL,
    [ENABLED] [char](1) NOT NULL,
    [SUPER_USER] [char](1) NOT NULL,
    [EMAIL] [varchar](100) NULL,
    [LAST_ACCESS] [datetime] NULL,
    [PREVIOUS_LOGIN] [datetime] NULL,
    [FIRST_NAME] [varchar](200) NULL,
    [LAST_NAME] [varchar](200) NULL,
    [CONTACT_INFO] [varchar](200) NULL,
    [CULTURE] [varchar](20) NULL DEFAULT ('sl-SI'),
 CONSTRAINT [PK_USER] PRIMARY KEY CLUSTERED 
(
    [USER_ID] ASC
))

GO

以下是我们创建索引的方式:

CREATE UNIQUE NONCLUSTERED INDEX [IX_USER_NAME] ON [dbo].[USER]
(
    [USER_NAME] ASC
))
GO

用户对象:

[ActiveRecord("USER", Lazy=true)]
public partial class User : ActiveRecordBase<User>
{
    [PrimaryKey("USER", "USER_ID")]
    public virtual int UserId { get; set; }

    [BelongsTo("COMPANY_ID")]
    public virtual Company RealCompany { get; set; }

    [Property("USER_NAME")]
    public virtual string UserName { get; set; }

    [Property("PASSWORD")]
    public virtual string Password { get; set; }

    [Property("ENABLED")]
    public virtual string Enabled { get; set; }

    [Property("SUPER_USER")]
    public virtual string SuperUser { get; set; }

    [Property("EMAIL")]
    public virtual string Email { get; set; }

    [Property("LAST_ACCESS")]
    public virtual DateTime? LastAccess { get; set; }

    [Property("PREVIOUS_LOGIN")]
    public virtual DateTime? PreviousLogin { get; set; }

    [Property("FIRST_NAME")]
    public virtual string FirstName { get; set; }

    [Property("LAST_NAME")]
    public virtual string LastName { get; set; }

    [Property("CONTACT_INFO")]
    public virtual string ContactInfo { get; set; }

    [Property("CULTURE")]
    public virtual string Culture { get; set; }

}

我们正在使用延迟加载,表在用户名列上有索引。我已经使用SQL Server Profiler检查了所有内容,并且查询NHibernate在数据库上执行的操作几乎立即返回。

NHibernate生成查询:

exec sp_executesql N'SELECT TOP (@p0) this_.USER_ID as USER1_40_0_, this_.USER_NAME as USER2_40_0_, this_.PASSWORD as PASSWORD40_0_, this_.ENABLED as ENABLED40_0_, this_.SUPER_USER as SUPER5_40_0_, this_.EMAIL as EMAIL40_0_, this_.LAST_ACCESS as LAST7_40_0_, this_.PREVIOUS_LOGIN as PREVIOUS8_40_0_, this_.FIRST_NAME as FIRST9_40_0_, this_.LAST_NAME as LAST10_40_0_, this_.CONTACT_INFO as CONTACT11_40_0_, this_.CULTURE as CULTURE40_0_, this_.COMPANY_ID as COMPANY13_40_0_ FROM [USER] this_ WHERE this_.USER_NAME = @p1;', N'@p0 int, @p1 varchar(100)', @p0 = 2, @p1 = N'username'

在应用程序启动时(仅)创建SessionFactory。每次请求都会创建NHibernate会话。

在第二次调用时,相同的查询在大约30ms内执行。

任何人都可以解释第一次这么长时间拍摄的内容吗?

更新1

应用程序池配置为自动启动。当应用程序池回收时,我们也会调用预热脚本。

在对各种情况进行额外测试并公开应用程序后,我们发现了同样的问题,如果Web应用程序处于一小时或两小时不活动状态。

0 个答案:

没有答案