2009-06-29 14 views
2

Derzeit arbeiten wir in der Bereitstellung eines OFBiz-basierten ERP, wir sind zu dem folgenden Problem gekommen: ein Teil des Codes des Frameworks ruft resultSet.last() auf, um die gesamten Zeilen des Resultsets zu kennen. Mit dem Oracle JDBC-Treiber v11 und v10 wird versucht, alle Zeilen im Client-Speicher zwischenzuspeichern, wodurch die JVM abstürzt, da nicht genügend Heap-Speicher zur Verfügung steht.Unterstützt Oracle serverseitige Scrollable-Cursor über JDBC?

Nach der Untersuchung scheint das Problem zu sein, dass die Oracle JDBC den Scrollable Cursor auf der Clientseite statt auf dem Server durch die Verwendung eines Cache implementiert. Mit dem Datadirect-Treiber ist dieses Problem gelöst, aber es scheint, dass der Aufruf von resultset.last() zu viel dauert, damit der Anwendungsserver die Transaktion abbricht

Gibt es eine Möglichkeit, scrollbare Cursor über jdbc in zu implementieren Oracle, ohne auf den Datadirect-Treiber zurückgreifen zu müssen?

und was ist der schnellste Weg, um die Länge eines bestimmten Ergebnisses zu wissen?

Vielen Dank im Voraus Ismael

+0

Ich werde zuerst eine Tangentenfrage stellen; Benötigen Sie die Daten und die Größe des Resultsets gleichzeitig oder können Sie einfach eine COUNT (*) Abfrage durchführen, um die Anzahl der Zeilen zu ermitteln? Brauchen Sie WIRKLICH die Anzahl der Zeilen auch, ich habe das zu oft gesehen, wo ein Programm die sehr teure Operation ausführt, um die Gesamtzahl der Zeilen für die Paginierung zu erhalten, wenn sie wirklich nicht benötigt wird. – Gandalf

+0

Es muss die Anzahl der Seiten in einem Paginierungsschema bestimmt werden. Wir versuchen, die Verwendung von last zu vermeiden und den currentIndex mit der Iterator next() -Methode auf Null zu zählen. Gibt es eine schnelle Möglichkeit, die Anzahl der Seiten zu kennen, ohne die last() -Methode zu verwenden? Unsere Problemumgehung besteht darin, eine COUNT-Abfrage mit denselben Bedingungen auszuführen und dann die Abfrage für die Daten auszuführen. – Ismael

+0

Muss der Benutzer die Anzahl der Seiten wissen? Gibt es einen gültigen Benutzerfall, in dem ein Benutzer direkt zur letzten Seite wechseln möchte? Normalerweise fragen wir nur nach einem weiteren Eintrag, der für eine Seite benötigt wird. Wenn dieser Eintrag existiert, setzen Sie einen Link für die "nächste" Seite - requery, um die nächste Seite zu erhalten. Angenommen, Ihre Daten haben eine Reihenfolge, nach der Sie sortieren können. – Gandalf

Antwort

1

„Was ist der schnellste Weg, um die Länge eines gegebenen resultSet wissen“ der einzige Weg, wirklich wissen, ist, sie alle zu zählen. Du willst wissen, wie viele 'SMITHs im Telefonbuch sind. Du zählst sie. Wenn es ein kleines Ergebnis ist, und schnell angekommen, ist es kein Problem. ZB Es wird nicht viele Gandalfs im Telefonbuch geben, und Sie wollen sie wahrscheinlich sowieso alle bekommen.

Wenn es sich um eine große Ergebnismenge handelt, können Sie möglicherweise eine Schätzung vornehmen, obwohl dies in der Regel nicht gut für SQL ist. Dann wird jede Zeile eine zusätzliche Spalte (in diesem Fall n) mit der Anzahl der Zeilen in der Ergebnismenge

Cachen das gesamte Ergebnis auf dem Client eingestellt zu vermeiden, können Sie

select id, count(1) over() n from junk; 

versuchen. Aber es wird immer noch die gleiche Zeit brauchen, um den Count zu erreichen, so dass es immer noch eine große Chance auf eine Auszeit gibt.

Ein Kompromiss ist die ersten hundert (oder tausend) Zeilen, und sorgen Sie sich nicht über die Paginierung darüber hinaus.

+0

+1: Während es schön wäre, die Anzahl der Zeilen zu kennen, die eine Abfrage zurückgibt, müssen diese Informationen berechnet werden und verursachen daher Kosten. Garys Antwort ist wahrscheinlich der billigste Weg, dies zu tun. –

0

Ihre vorgeschlagene "Workaround" mit Anzahl im Grunde verdoppelt die Arbeit von DB-Server getan. Es muss zuerst alles durchgehen, um die Anzahl der Ergebnisse zu zählen und dann die gleichen + Ergebnisse zurückgeben. Viel besser ist die von Gary erwähnte Methode (count (*) over() - analytics). Aber auch hier muss die gesamte Ergebnismenge erstellt werden, bevor die erste Ausgabe an den Client zurückgegeben wird. Es ist also möglicherweise ein langsamer Speicher für große Ausgaben.

Der beste Weg ist meiner Meinung nach nur die gewünschte Seite auf dem Bildschirm auswählen (+1 zu bestimmen, dass der nächste existiert) z. Zeilen von 21 bis 41. Und haben einen anderen Knopf (Usecase), um sie alle in dem (seltenen) Fall zu zählen, der jemand es benötigt.