nhibernate hql子查询性能

nhibernate hql子查询性能,nhibernate,hql,castle-activerecord,Nhibernate,Hql,Castle Activerecord,我已经编写了一个hql来支持分页 string hql = @"select distinct mr from MediaResource as mr where mr.Deleted= false and mr.Type = :typeId"; SimpleQuery<Medi

我已经编写了一个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语句,使其只有一个查询?

除非您有大量记录,否则性能损失可能不会明显。在这种情况下,您将收回所有记录,然后获取所需内容

另一种方法是使用如下内容:

 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 top,其中id>xx

除非有大量记录,否则性能损失可能不会明显。在这种情况下,您将收回所有记录,然后获取所需内容

另一种方法是使用如下内容:

 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 top,其中id>xx

,除非如ddango所述,有大量行,否则这不会是一个性能问题。您的查询是从子查询中进行选择,而不是对数据库服务器运行两个单独的查询,这是一些人所做的,对性能来说是可怕的。您将只在查询结束时返回正确的结果集,我相信要使用rowcount以这种方式工作,需要运行一个子查询

我的建议是保持原样,如果表被正确地索引用于搜索,那么在速度上不应该有任何问题,因为查询实际上并不像在数据库端那样昂贵,这并不是说您实际上要将子查询中每个对象的详细信息拉到应用程序中,并将它们构建到对象中

至于你的另一个问题

可以告诉Nhibernate生成sql语句,使其只有一个查询吗


我不相信NHibernate可以被触发来隐式生成更多的最优解决方案,改变这一点的唯一方法是改变您获取此数据的方法,但我自己认为子查询没有任何问题:

据我所知,这不会是性能问题,除非如ddango所述,有大量的争吵。您的查询是从子查询中进行选择,而不是对数据库服务器运行两个单独的查询,这是一些人所做的,对性能来说是可怕的。您将只在查询结束时返回正确的结果集,我相信要使用rowcount以这种方式工作,需要运行一个子查询

我的建议是保持原样,如果表被正确地索引用于搜索,那么在速度上不应该有任何问题,因为查询实际上并不像在数据库端那样昂贵,这并不是说您实际上要将子查询中每个对象的详细信息拉到应用程序中,并将它们构建到对象中

至于你的另一个问题

可以告诉Nhibernate生成sql语句,使其只有一个查询吗


我不相信NHibernate可以被触发来隐式生成更多的最优解决方案,改变这一点的唯一方法是改变您获取此数据的方法,但我自己认为子查询没有任何问题:

我一开始没有注意到,但由于您使用的是ActiveRecord,我不确定这些方法是否在SimpleQuery上公开。我认为您可能需要使用session.CreateQuery,具体如下:谢谢您的回复。但我选择ActiveRecord而不是纯NHibernate的主要原因是我不想把会话搞砸。不过,我会考虑切换,我觉得更舒适的框架工作。我最初没有注意到,但既然你正在使用ActuvReCordD,我不知道这些方法是否暴露在一个简单的。我认为您可能需要使用session.CreateQuery,具体如下:谢谢您的回复。但我选择ActiveRecord而不是纯NHibernate的主要原因是我不想把会话搞砸。不过,我会考虑开关一次,我觉得更舒适的框架工作。谢谢澄清。现在我感觉舒服多了。谢谢你的澄清。现在我感觉舒服多了。