【问题标题】:Hibernate (/JPA) server-side paging and MS SQL ServerHibernate (/JPA) 服务器端分页和 MS SQL Server
【发布时间】:2012-03-26 08:23:35
【问题描述】:

我用hibernate / JPA实现了一个服务器端数据分页,底层数据库是MS SQL Server 2008。

SQL 是这样生成的:

criteria.setFirstResult(pagingParams.getDisplayStart())
.setMaxResults(pagingParams.getDisplayLength());

(主要工作在于创建适当的过滤器/排序,但这与这里无关)

我观察到的是以下 SQL:

page (0-20):
select top 20 this_.id as id11_9_,...

page (20-40):
select top 40 this_.id as id11_9_,... 

page (40-60):
select top 60 this_.id as id11_9_,... 

...等等。

显然,如果底层结果集太大,这 (a) 将遇到严重问题,并且 (b) 与分页没有太大关系:-(

有人遇到过同样的问题吗?

更新:似乎 T-SQL 的 Row_Number() 函数的 NHibernate(Hibernate 的 .NET 实现)takes advantage。可惜 Hibernate 没有...

【问题讨论】:

    标签: sql-server sql-server-2008 hibernate jpa orm


    【解决方案1】:

    回复有点晚,但它可能会有所帮助,所以我会发布它。有完全相同的问题,并且很难找到它。解决方案是使用 Hibernate 4.3.0 中包含的org.hibernate.dialect.SQLServer2012Dialect。生成的查询变为(粘贴没有列名和别名的真实 Hibernate 转储):

    WITH query 
         AS (SELECT inner_query.*, 
                    Row_number() 
                      OVER ( 
                        ORDER BY CURRENT_TIMESTAMP) AS __hibernate_row_nr__ 
             FROM   (SELECT TOP(?) <COLUMN_NAMES> AS <ALIASES>
    FROM <TABLE_NAME>
    ) inner_query) 
    SELECT <ALIASES>
    FROM   query 
    WHERE  __hibernate_row_nr__ >= ? 
           AND __hibernate_row_nr__ < ?
    

    注意内部查询和Row_number() 函数的使用。他们终于解决了!

    【讨论】:

      【解决方案2】:

      我们还在使用 hibernate.dialect=org.hibernate.dialect.SQLServerDialect(使用 SQL Server 2008 R2)的 Hibernate 3.3 中观察到了同样的行为。

      我的印象是,当结合使用 Hibernate >= 3.5、将 hibernate.dialect 设置为 org.hibernate.dialect.SQLServer2005Dialectorg.hibernate.dialect.SQLServer2008Dialect、使用 SQL Server >= 2005 以及可能还使用 SQL Server 驱动程序 JDBC >= 时,这个性能问题就会消失3.0.

      支持上述印象的其他链接:

      【讨论】:

      • 根据引擎版本使用特定方言时性能得到很好的提升。在 SQL Server 2008 上测试,有 70 000 个结果,到达最后一页时执行时间减少了近 5 倍
      【解决方案3】:

      这是因为 MSSQL 没有为此版本提供真正的分页实现。确实有可能使用带有 Row_Number() 的内部查询,但就像你提到的那样,Hibernate 不使用它。

      我发现某些人修改了 SQLServer2008Dialect.java 以使其使用 Row_Number()。 follow this link

      编辑:(我注意到这些文件的来源不再可用)

      在 MSSQL2012 中,这个问题应该得到解决,因为它们实现了分页功能。剩下的唯一问题是这个版本的 MSSQL 没有特定的方言。他们建议使用旧版本(MSSQL2008),但这会导致同样的分页问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-01
        • 1970-01-01
        • 2016-12-13
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2014-05-17
        • 1970-01-01
        相关资源
        最近更新 更多