【问题标题】:nhibernate hql subquery performancenhibernate hql 子查询性能
【发布时间】:2009-12-15 03:01:10
【问题描述】:

我写了一个hql来支持分页

            string hql = @"select distinct mr 
                       from MediaResource as mr
                        where     mr.Deleted= false
                            and   mr.Type = :typeId";

            SimpleQuery<MediaResource> q = new SimpleQuery<MediaResource>(hql);
            q.SetParameter("typeId", typeId);
            q.SetQueryRange(page * pageSize, pageSize);
            return q.Execute().ToList();

然后我写了一个测试来运行这个函数并将nhibernate日志作为

 select
    * 
from
    ( select
        distinct mediaresou0_.MediaResourceID as MediaRes1_7_,
    from
        MediaResource mediaresou0_ 
    where
        mediaresou0_.Deleted=0 
        and mediaresou0_.Type=:p0 ) 
where
    rownum <=:p1;
:p0 = 1, :p1 = 10

我关心的是 select * from (select ...) 部分。这会是性能问题吗?是否可以告诉 Nhibernate 生成 sql 语句只有一个查询?

【问题讨论】:

    标签: nhibernate hql castle-activerecord


    【解决方案1】:

    据我所知,除非像 ddango 提到的那样,存在大量行,否则这不会是性能问题。您的查询是从子查询中选择的,而不是对数据库服务器运行两个单独的查询,这是某些人所做的(并且对于性能来说是可怕的)。您只会在查询结束时返回正确的结果集,我相信它以这种方式工作(使用行数)需要运行子查询。

    我的建议是保持原样,如果表被正确索引以进行搜索,那么您不应该有任何速度问题,因为查询实际上并没有那么昂贵,因为它都是在数据库端完成的,它不是就像您实际上将子查询中每个对象的详细信息提取到您的应用程序并将它们构建到对象中一样。

    至于你的其他问题

    是否可以告诉 Nhibernate 生成 sql 语句只有一个查询?

    我不相信 NHibernate 可以被触发以隐式生成更优化的解决方案,改变这一点的唯一方法是改变你获取这些数据的方法,但我自己没有看到子查询有任何问题:)

    【讨论】:

    • 感谢您的澄清。现在我感觉舒服多了。
    【解决方案2】:

    除非您有大量记录,否则性能损失可能不会很明显。在这种情况下,您将撤回所有记录,然后拿走您想要的。

    另一种方法是使用这样的东西:

     SimpleQuery<MediaResource> q = new SimpleQuery<MediaResource>(hql);
            q.SetParameter("typeId", typeId);
            q.SetFirstResult(page * pageSize).SetMaxResults(pageSize);
            return q.Execute().ToList();
    

    SetFirstResult 会像它说的那样做——它设置索引,从那里获取结果。

    SetMaxResults 然后解决这个问题并获取 pageSize 行数。 (实际上是一个 sql 顶部,其中 id > xx)

    【讨论】:

    • 一开始我没有注意到,但由于您使用的是 ActiveRecord,我不确定这些方法是否在 SimpleQuery 上公开。我认为您可能需要使用 session.CreateQuery,详见此处:castleproject.org/ActiveRecord/documentation/v1rc1/usersguide/…
    • 感谢您的回复。但是我选择 ActiveRecord 而不是纯 NHibernate 的主要原因是我不想弄乱 Session。但是,一旦我对框架工作感到更舒服,我会考虑切换。
    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多