2016-08-03 13 views
0

Wenn ich eine Tabelle mit drei Spalten,Oracle JDBC-Speicherzuweisung beim Abrufen eines Suchresultates

NAME (VARCHAR2 20), AGE (NUMBER), LOCATION (VARCHAR2 50) 

, wie viel Arbeitsspeicher hat Oracle JDBC-Treiber zuweisen, bevor das Ergebnis zu holen?

Wenn die fetch size bei 100 gesetzt ist, wird zuteilen der Treiber Speicher für alle 100 Datensätze selbst wenn die Abfrage nur 10?

Dank

+0

[Siehe dieses] (http: //stackoverflow.com/questions/8234087/where-result-set-is-stored-while-working-with-jdbc-and-oracle-driver). Soweit ich weiß, würde der zugewiesene Speicher im Java-Heap niemals die tatsächliche Anzahl der Zeilen überschreiten. [Siehe auch hier] (http://stackoverflow.com/questions/6651250/resultset-memory) –

Antwort

0

Der Oracle-Treiber ordnet fechtsize * max. size of one row.

In Ihrem Fall wäre dies 40 Bytes (= 20 Zeichen in UTF-16) + 22 Bytes + 100 Bytes (= 100 Zeichen in UTF-16) * 100. Das ergibt insgesamt etwa 16kb (wahrscheinlich ein bisschen mehr)

Dies ist eigentlich die einzige Wahl des Treibers: Wenn Sie den Treiber bitten, 100 Zeilen über das Netzwerk zu senden, muss genügend Speicher zugeordnet werden, um diese 100 Zeilen im Speicher zu halten. Das bedeutet, dass es den schlimmsten Fall annehmen und die maximale Länge für jede Spalte reservieren muss.

Sobald die Daten vom Server empfangen werden, wird nur so viel Speicher benötigt wie erforderlich, nachdem sie in die richtigen Java-Objekte konvertiert wurden.

Sie können sich die Abrufgröße anzeigen lassen, um einen Puffer zuzuweisen, der während der Suchvorgänge verwendet wird. Ähnlich wie z.B. a BufferedInputStream

+0

Ich bin nicht in die interne Implementierung des Oracle JDBC-Treibers eingeweiht, aber es ist nicht notwendig, Speicher im Voraus zu reservieren: es könnte auch Objekte zuweisen, wie sie empfangen werden: so werden keine Zeilen mehr empfangen == kein zusätzlicher Speicher zugewiesen. –

1

Oracle Database JDBC-Treiber, Versionen vor 12:

Der Treiber ordnet die maximale Größe für jede Spalte mal die Abfrage, die Anzahl der Zeilen in dem fetchSize vor der Ausführung.

Zum Beispiel für eine VARCHAR(4000) Spalte wird es 8k Bytes mal die fetchSize zuweisen.


Versionen 12 (und höher):

Es weist etwa 15 Bytes pro Spalte pro Zeile in der fetchSize vor dem Ausführen der Abfrage. Nach der Ausführung weist der Treiber in Version 12 nur soviel zu, wie zum Speichern der eigentlichen Zeilendaten erforderlich ist.

Als Ergebnis verwenden Treiber der Version 12 in der Regel wesentlich weniger Speicher als die Treiber der früheren Versionen.


Ihr Beispiel:

In Ihrem Beispiel ein VARCHAR(20) als 40 Bytes, so groß sein, kann ein NUMBER als 22 Bytes, wie groß sein und ein VARCHAR(100) so groß wie 100 Byte. Wenn der fetchSize auf 100 gesetzt ist, würden die älteren Treiber (40 + 22 + 100) * 100 = 16k zuweisen. Der Treiber der Version 12 würde 3 * 15 * 100 = 4.5k zuweisen.Es gibt einen zusätzlichen Overhead in beiden Treibern, den ich ignoriere.

0

Sie können eintauchen: http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf

Wie Sie es hängt Faktoren der Version von JDBC-Treiber, Treiberkonfiguration (aktiviert der Vorbereitung Statement Cache oder nicht, Parameter Sie vorbei Option -D) und viele viele andere sehen können .

Es hängt sogar von anderen SQL-Anweisungen ab, die Sie in Ihrer Anwendung haben.

Im besten Fall wird der Treiber keinen Speicher zuweisen, sondern nur Puffer aus dem vorherigen Aufruf der gleichen oder einer anderen Anweisung (abhängig von vielen Faktoren natürlich).

Im schlimmsten Szenario so viel Speicher Betrag zuteilen wird, wie Sie durch den anderen SQL-Anweisung Aufruf Daten abrufen müssen für die Sie in Statement Cache bereits vorbereiten (für Oracle JDBC < 11.2)