2012-03-26 12 views
7

ich einen serverseitige Daten Implementierung von Paging mit wintern/JPA, die zugrunde liegende Datenbank ist MS SQL Server 2008.Hibernate (/ JPA) serverseitige Paging und MS SQL Server

Die SQL wird wie folgt generiert:

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

(die Hauptarbeit legt die entsprechenden Filter in der Erstellung/Sortierung, aber das ist hier nicht relevant)

Was ich beobachte, ist das folgende 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_,... 

... und so weiter.

Offensichtlich ist dies (a) wird in ernsthafte Probleme ausgeführt werden, wenn das zugrunde liegende Suchresultates zu groß wird und (b) hat nicht viel mit Paging zu tun, überhaupt :-(

Wer hatte das gleiche Problem?

aktualisieren: Es scheint, als ob NHibernate (die .NET-Implementierung von Hibernate) takes advantage der Row_Number() Funktion von T-SQL Schade, dass Hibernate nicht ...

Antwort

8

Ein bisschen späte Antwort, aber es kann hilfreich sein, damit ich es posten werde.Hatte genau das gleiche Problem und Kopfschmerzen, um es aufzuspüren. Lösung ist org.hibernate.dialect.SQLServer2012Dialect, die in Hibernate 4.3.0 enthalten ist. Generierte Abfrage wird (Einfügen von Echt Hibernate-Dump ohne Spaltennamen und Aliasnamen):

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__ < ? 

Beachten Sie die Verwendung von innerer Abfrage und Row_number() Funktion. Sie haben es endlich gelöst!

4

Wir beobachteten auch das gleiche Verhalten mit. Hibernate 3.3 mit hibernate.dialect=org.hibernate.dialect.SQLServerDialect (wi SQL Server 2008 R2).

Mein Eindruck ist, dass diese Leistung Problem verschwindet, wenn die Kombination von Hibernate mit> = 3,5, Einstellung hibernate.dialect zu org.hibernate.dialect.SQLServer2005Dialect oder org.hibernate.dialect.SQLServer2008Dialect, mithilfe von SQL Server> = 2005 und wahrscheinlich auch SQL Server-Treiber JDBC> = 3,0.

Weiterführende Links die oben Eindruck sichern:

+0

Die Leistung wurde bei der Verwendung eines bestimmten Dialekts entsprechend der Engine-Version verbessert. Getestet auf SQL Server 2008 mit 70 000 Ergebnissen. Die Ausführungszeit wurde beim Erreichen der letzten Seite um fast 5 Mal reduziert – yodamad

2

Das ist, weil es keine wirkliche Paging-Implementierung von MSSQL für diese Version zur Verfügung gestellt ist. In der Tat gibt es die Möglichkeit, eine innere Abfrage mit Row_Number() zu verwenden, aber wie Sie erwähnt haben, verwendet Hibernate dies nicht.

Ich habe festgestellt, dass bestimmte Personen den SQLServer2008Dialect.java geändert haben, damit er Row_Number() verwendet. follow this link

EDIT: (Ich habe die Quelle dieser Dateien bemerkt ist nicht mehr verfügbar)

In MSSQL2012 dieses Problem gelöst werden soll, weil sie Paging-Funktionalitäten implementiert. Das einzige verbleibende Problem besteht darin, dass es für diese Version von MSSQL keinen spezifischen Dialekt gibt. Sie schlagen vor, die alte (MSSQL2008) zu verwenden, aber dies wird zu den gleichen Paging-Problemen führen.