簡體   English   中英

為什么我的NHibernate查詢這么慢?

[英]Why are my NHibernate queries so slow?

我正在使用Fluent NHibernate v2.0.50727到SQL Server后端構建ASP Web表單應用程序。

出於某種原因,查詢具有小數據(約14行)的表需要幾秒鍾。

映射都很簡單: Id(x => x.Id)Map(x => x.Name) CertificateGroup還Map()的ColorRank

我已經隔離了用於測試的nhibernate代碼:(這不代表我的應用程序,但是針對SO進行了簡化和隔離)

protected void Page_Load(object sender, EventArgs e)
{
    var config = Fluently.Configure()
                             .Database(MsSqlConfiguration.MsSql2008.ConnectionString("..."))
                             .Mappings(m => m.FluentMappings.AddFromAssemblyOf<PersonMap>())                                 .BuildConfiguration();
    var factory = config.BuildSessionFactory();

    using (var session = factory.OpenSession())
    {
        using (var transaction = session.BeginTransaction())
        {
            var departments = session.QueryOver<DepartmentModel>().List(); // these all take seconds to execute - this has 14 results
            var jobs = session.QueryOver<JobModel>().List(); // 113 results
            var certificates = session.QueryOver<CertificateModel>().List(); //this one about 4 seconds for 210 results
            var groups = session.QueryOver<CertificateGroupModel>().List();

            var association = new CertificateAssociationModel
                {
                    Department = departments.First(),
                    Job = jobs.First(),
                    Certificate = certificates.First(),
                    Group = groups.First()
                };
            session.SaveOrUpdate(association);
            transaction.Commit();
        }
    }
}

我將nhibernate交換為實體框架,並運行了上面的代碼,並且獲取是即時的。

任何幫助表示贊賞。

編輯:

這是映射(如我上文所述):對於部門,職位和證書:

public class DepartmentMap : ClassMap<DepartmentModel>
{
    public DepartmentMap()
    {
        Table("tblDepartment");
        Id(x => x.Id);
        Map(x => x.Name);
    }
}

CertificateGroupModel還具有Map(x => x.Rank); Map(x => x.Color);

實體類都是相同的:

public class CertificateModel
{
    public virtual Int32 Id { get; protected set; }
    public virtual String Name { get; set; }
}

除了CertificateGroupModel之外,它還具有:

public virtual String Color { get; set; }
public virtual Int32 Rank { get; set; }

這是我的NHiberate分析器結果:

 -- statement #1
begin transaction with isolation level: Unspecified

-- statement #2
SELECT this_.Id   as Id4_0_,
       this_.Name as Name4_0_
FROM   tblDepartment this_

-- statement #3
SELECT this_.Id   as Id5_0_,
       this_.Type as Type5_0_
FROM   tblJobTitles this_

-- statement #4
SELECT this_.Id   as Id2_0_,
       this_.Name as Name2_0_
FROM   tblCertificate this_

-- statement #5
SELECT this_.Id    as Id1_0_,
       this_.Name  as Name1_0_,
       this_.Rank  as Rank1_0_,
       this_.Color as Color1_0_
FROM   tbl_certificate_groups this_

-- statement #6
INSERT INTO lnk_certificate_associations
            (Certificate_id,
             Department_id,
             Job_id,
             Group_id)
VALUES      (1 /* @p0 */,
             1 /* @p1 */,
             1 /* @p2 */,
             1 /* @p3 */);



select SCOPE_IDENTITY()


-- statement #7
commit transaction

nhibprofile http://i.snag.gy/bTKHm.jpg

IL代碼生成:

                      var departments = session.QueryOver<DepartmentModel>().List();
IL_008F: ldloc.2      /* session */
IL_0090: callvirt     instance NHibernate.IQueryOver`2<!!0, !!0> NHibernate.ISession::QueryOver<Core.Domain.Model.DepartmentModel>()
IL_0095: callvirt     instance [mscorlib]System.Collections.Generic.IList`1<!0> NHibernate.IQueryOver`1<Core.Domain.Model.DepartmentModel>::List()
IL_009A: stloc.s      departments

推測一下,由於您尚未在此處發布映射和表格...

您的數據庫中是否有任何可為空的列已映射為不可為空的類型(例如,可為null的int映射為模型中的int)?

這可能會引起您所看到的某種行為,因為當NHibernate加載您的實體時(假設上面的DepartmentModel場景,其屬性Prop1為int),如果Prop1在數據庫中為null,則該會話將具有一個內部狀態為null,但由於您無法將Prop1設置為null,因此將其分配為0,並且當會話檢查是否有任何更改時,它將看到Prop1已更改(從null變為0),並導致整體一堆更新,這反過來會減慢很多速度。

在這種情況下,解決方案是更新表定義或更新實體以具有正確的(可空)類型。

發生這種情況的方式有很多種,我只是舉了一個簡單的例子-如果您可以包括映射,表定義和實體類,這將很有幫助...

至於插入問題,如果您將身份生成器用於Id,則nHibernate首先會要求數據庫( INSERT...SELECT SCOPE_IDENTITY() )為您的實體創建記錄,然后使用正確的ID和數據將其插入( UPDATE

請注意,對其他實體的引用將在UPDATE因此您只會看到'?' 在插入

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM