ResultSet, Performance

Status
Nicht offen für weitere Antworten.

Schreihalz

Mitglied
Hallöchen allerseits...

Ich habe folgendes Problem:
3 Tabellen werden in der Datenbak ausgelesen (Oracle). Alle 3 Selects sind PreparedStatements. Das Auslesen geschieht parallel in 3 Threads. Jeder Thread hat jeweils eine Connection und 1 PrepareStatement. Mein Ziel ist es: das Auslesen so schnell wie möglich zu machen, nur irgendwie klappt das nicht ganz. Die selects haben jeweils so um die 20 Spalten und zur zeit werden so um die 500 Zeilen Selected. Die Zeiten die ich erziele schwanken sehr stark von
100 ms bis 2 sek.
die 3 Threads stocken manchmal richtig an der Stelle, wo ich die ResultSets in die Container-Objekte überführe.

als Beispiel für eine Tabelle einwenig Quellcode:

im Thread:

Code:
private void fillAccounts() {
        try {
            ResultSet rs_accounts = prep_selectAccounts.executeQuery();
            while (rs_accounts.next()) {
                [b]AccountContainer accCont = new AccountContainer(rs_accounts);[/b]
                resultList.add(accCont);
            }
            rs_accounts.close();
        } catch (Exception sqle) {
            sqle.printStackTrace();
            //this.log.error(....);
        }
    }

Und der Konstruktor, der da aufgerufen wird:

Code:
      public AccountContainer(ResultSet rs_accounts) {
		try{
			this.setBla1(rs_accounts.getDouble("BLA1"));
			this.setBla2(rs_accounts.getString("BLA2"));
			this.setBla3(rs_accounts.getDouble("BLA3"));
                        ..............
			this.setBla21(rs_accounts.getBoolean("BLA21"));
			this.setBla22(rs_accounts.getString("BLA22"));
			this.setBla23(rs_accounts.getDouble("BLA23"));
		}
		catch(SQLException sqle){
			sqle.printStackTrace();
			//this.log.error(sqle);
		}
	}

hat denn jemand eine Idee, wie ich es schneller und konstanter bekomme. Ich habe die Vermutung, dass JVM an der Stelle, wo diese Konstruktoren je nach Tabelle in der Schleife bis zu 500 mal (Ist ja eigentlich gar nicht so viel) aufgerufen werden, mit der Verteilung der Ressourcen einfach nicht zurecht kommt oder so... Ich hatte schon versucht, den Threads unterschiedliche Prioritäten zuzuweisen, aber so richtig was hat es nicht gebracht.
 

semi

Top Contributor
Sieht eigentlich gut aus. Da gibt es kaum was zu optimieren.
Aber bis zu 2 Sekunden sind schon heftig. Bist Du sicher, dass Du keine
Table-Locks hast oder dass sich die Threads gegenseitig blockieren?
Wenn die Daten häufig abgefragt werden, wäre ein Cache auch eine Lösung.
Ansonsten versuche vielleicht die Größe der Collection vorher auf einen Erfahrungswert
zu setzen, damit sie beim Einfügen nicht umkopiert/vergrößert werden muss.
z.B.
Code:
Collection resultList = new ArrayList(500);
(Bringt aber nicht besonders viel)

Edit: Noch eine Kleinigkeit. Auf ResultSet über Index (Paar Konstanten dazu schreiben),
statt Spaltennamen zugreifen. Es erspart ziemlich viele Stringvergleiche in ResultSet.
Wieder paar Millisekunden ;)
Danach kannst Du vielleicht noch den Aufwand treiben und versuchen die AccountContainer-Objekte
wieder zu verwenden. Stichwort: "Object pool", "Instance pool" etc.
 

Schreihalz

Mitglied
sind doch schon mal paar Ansätze, die man verfolgen kann. Locks können es nicht sein, weil ich noch der einzige bin, der auf die DB zugreift. Ich versuche es mal mit den Indizies, es hört sich vernünftig an, die Stringvergleiche mag ich auch nicht.

Ein Cache wäre wohl das Sinnvollste. Da fehlt 1. die Erfahrung und das wichtigste: die Zeit ;) vielleicht findet man sie mal

danke auf jeden Fall :)
 

semi

Top Contributor
Apropos Indizies. Wie performant ist die SQL Abfrage selbst?
Manchmal wirkt ein zusätzlicher Index in der Tabelle oder
eine etwas anders formulierte Abfrage Wunder.
 

Schreihalz

Mitglied
die Abfrage ist sehr schnell.. da besteht kein Grund zur Sorge. Immerhin etwas, worauf man sich ab und zu verlassen kann :)
Die Messungen ergeben: die While-schleife verbraucht fast alles, wenns mal langsam wird
 

Bleiglanz

Gesperrter Benutzer
vergiss die threads! "jeder hat eine Connection"???

=> der Verbindungsaufbau selbst ist schon aufwändig, verwende lieber EINE Connection!!

und lies die 3 nacheinander ein, was soll denn die Parallelisierung bringen??

schreib dir eine Stored Proc, die alle drei Ergebnisse auf einmal liefert und verwende dann z.B. statement.getMoreResults (ohne Stored Proc gehts möglicherweise auch mit execute("SELECT ..; SELECT .."))

usw
 

Bleiglanz

Gesperrter Benutzer
Nachtrag: wenn du Java5 hast und dich ein bisschen ins CachedRow Set einarbeiten willst, das ist oft einfacher als die ganzen "Accout-Stellvertreter-Objekte" mit new zu erzeugen

=> schmeiss alles in ein RowSet und mach aus dem AccountContainer einen Proxy (ohne Member!) für die zuständige Zeile...
 

semi

Top Contributor
Es gab mal eine Seite www.irongrid.com, wo eine ziemlich gute Cache Lösung
verfügbar war (IronEye Cache). Die Seite ist aber verschwunden. ???:L
Es wird zwischen den JDBC-Treiber und die Datenbank geschaltet und cacht,
was das Zeug hält. Am Code muss man nix ändern.
Auch das IronTrack SQL war nett, um die Performance der Abfragen zu bestaunen.
Ich habe beides immer noch, falls Du es haben möchtest, aber wenn Du es
in einem komerziellen Projekt verwendest, dann ist auch Kontinuität wichtig
bzw. das die eingesetzten Tools keine Leichen sind, die nicht mehr weiterentwickelt
werden. Hmm...

Habe gerade noch etwas anderes über Google gefunden http://isocra.com/livestore/,
kann aber nix dazu sagen, kenne es nicht. Ich habe nach "JDBC Cache" gesucht.

Meine Erfahrung ist, dass Strings und Typenkonvertierungen im Allgemeinen die meiste
Zeit schlucken.

Beschränkst Du die Anzahl der Datensätze bei den Abfragen auf 500 Datensätze oder
liest Du was kommt und dann nur die ersten 500? Da wäre nämlich noch was zu optimieren.
ResultSet.setFetchSize(500)
 

semi

Top Contributor
Bleiglanz hat gesagt.:
Nachtrag: wenn du Java5 hast und dich ein bisschen ins CachedRow Set einarbeiten willst, das ist oft einfacher als die ganzen "Accout-Stellvertreter-Objekte" mit new zu erzeugen

=> schmeiss alles in ein RowSet und mach aus dem AccountContainer einen Proxy (ohne Member!) für die zuständige Zeile...
Gute Lösung. CachedRowSet ist schnell. Auch unter JDK 1.4 verwendbar. Googeln.
 
G

Gast

Gast
1. ich habe kein java5 (1.4.2)
2. Connections werden nur am anfang einmal aufgebaut und nur beim Modulstop geclosed.. (Threads warten nur zwischen den Selects) ich habe mit den 3 Threads auch mal 1 Connection geteilt und die Ergebnisse kann man sich vorstellen (langsamer) deswegen 3 Connections
3. Parallelisierung: Das Dingen muss eben schnell sein, obs man es zum Teil mit Threads erreicht sei mal dahin gestellt, denn ich entscheide nicht alles.

Was mich jetzt aber interessiert:
"statement.getMoreResults ... (ohne Stored Proc gehts möglicherweise auch mit execute("SELECT ..; SELECT ..")) "

kannst du es bitte etwas näher erläutern (also ohne strored proc) ? oder vielleicht nur einpaar stichworte oder links?
 

Schreihalz

Mitglied
gast-posting war von mir.. komischerweise war ich plötzlic hausgeloggt :/
Muss erstma prioritäten setzen wo ich anfange ;)
Das nächste was ich wohl anstellen werde ist also googeln nach Cache und CachedRowSet
 

Bleiglanz

Gesperrter Benutzer
Threads machen das ganze auf einem 1Prozessor Rechner LANGSAMER, hast du da noch nie etwas davon gehört?

selbst bei einem extrem langsamen netzwerk dürfte durch das switchen zwischen den Threads + IO viel Overhead entstehen...

wenn dreimal parallel rs.next() aufgerufen wird, dann wird ja immer ein anderer Socket bedient, ich kann mir nicht vorstellen, dass 3 threads hier schneller arbeiten als 3 mal hinteireinander alles auf einen Rutsch holen...

zum getMoreResults: oft ist es möglich, dass ein einziger Request an eine DB MEHRERE Resultsets zurückliefert; am einfachsten machst du das über eine StoredProc

oder versuch mal den String

"SELECT FROM A; SELECT FROM B; SELECT FROM C"

abzusetzen, manche Treiber können dir dann 3 Resultsets geben
 

Bleiglanz

Gesperrter Benutzer
Schreihalz hat gesagt.:
es ist eine Maschine mit 2 Hyperthreading Prozessoren (Also quasi 4 Prozessoren)

lies lieber mal nach, ob deine JVM das überhaupt ausnutzt (ist nicht immer der Fall)!

ausserdem hat das Ding wahrscheinlich nur eine Netzwerkkarte? Bei langsamer IO könntest du aber tatsächlich "schneller" sein, wenn du die Resultsets parallel von der DB holst, aber bei läppischen 1500 Sätzen würde mich das wundern

-> schon einen Vergleich mit der Single-Threaded Version gemacht? :)

dabei fällt mir noch was auf

Code:
while(rs.next()){

     objekt = new ValueObject(rs); // aufwändige Objekterzeugung

}
ist ungünstig, weil das resultset länger offen ist als unbedingt nötig, ausserdem soll man das rs nicht herumreichen; für den server ist es besser, wenn man so schnell wie möglich durch-iteriert

würde eher das ValueObject vom sql entkoppeln und mir vorher über Metadaten die indizes holen (wie oben schon angeregt), der Konstruktor soll nur noch triviales Kopieren der Werte vornehmen

Code:
int wert1_index = ...// über resultsetmetadata den index der spalte holen
int wert2_index = ...// usw.


while(rs.next()){
 
     objekt = new ValueObject(rs.getString(wert1_index), rs.getInt(wert2_index), ...); // einfacher Wertkonstruktor

}
 

Schreihalz

Mitglied
Ok, das mit den Indizies habe ich gemacht, das hat etwas gebracht.. immerhin.

Das interessanteste ist jetzt ob die JVM das Multithreading mitmacht... Es ist tatsächlich so, das ich hier euf meinem Laptop entwickle und die Zeiten unterscheiden sich vom grossen Rechner kaum. Man muss wohl an der stelle JVM was unternehmen oder? Aber kann da was machen, verändern, einstellen oder muss man eine komplett andere(bestimmte) JVM aufsetzen?
 

AlArenal

Top Contributor
Mein Kenntnisstand:

Die Threads in Java haben derzeit mit den Threads im jeweiligen OS nichts zu tun. Habe ich 30 parallele Threads in einer Java-Anwendung, ist diese auf System-Ebene nur als ein Prozess vertreten. Erst Java 6 soll dahingehend Abhilfe schaffen.

Mit paralleleln Threads ist in diesem Fall also keine wirkliche Performance-Steigerung möglich. Der erhöhte Aufwand für Synchronisation und Scheduling dürfte die Gesamtperformance der Anwendung eher verringern.
 

Bleiglanz

Gesperrter Benutzer
irgendwas passt wohl nicht, nimm mal -Xprof oder einen Profiler zur Hand

2 sekunden für 1500 Datensätze ist auf jeden fall nicht normal, selbst wenn du für jeden ein kleines (oder grosses) new aufrufst!

die bremse ist wahrscheinlich woanders :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S ResultSet als Parameter an andere Klasse übergeben Datenbankprogrammierung 3
Z ResultSet ist null warum? Datenbankprogrammierung 12
R HSQLDB ResultSet update aktualisiert DB, aber nicht das ResultSet Datenbankprogrammierung 2
Dimax Erstellen ResultSet und Statement Datenbankprogrammierung 30
C PostgreSQL ResultSet.TYPE_SCROLL_SENSITIVE setzen Datenbankprogrammierung 2
L MySQL Bekomme einen Fehler beim ResultSet Datenbankprogrammierung 12
L Zugriff auf ein Resultset Datenbankprogrammierung 7
L MySQL ResultSet vollständig auslesen Datenbankprogrammierung 20
D Resultset schließen ?? Datenbankprogrammierung 5
T Oracle Resultset to Array sehr langsam. Datenbankprogrammierung 8
B Probleme mit java.sql.SQLException: ResultSet closed Datenbankprogrammierung 21
J SQLite ResultSet closed -- Wiederholende DB-Abfragen Datenbankprogrammierung 6
Z MySQL Probleme mit resultSet executQuery Datenbankprogrammierung 3
L ResultSet Datenbankprogrammierung 1
J wie mit resultset.next() über Datensätze iterieren? Datenbankprogrammierung 15
R MySQL Umgang mit ResultSet/Fremdschlüssel ausgeben Datenbankprogrammierung 2
D MySQL ResultSet als Stream weiter geben Datenbankprogrammierung 9
M ResultSet Cachen Datenbankprogrammierung 3
R ResultSet mit "Untertabellen" Datenbankprogrammierung 4
N SQL-Statement Auslesen des Resultset wird immer langsamer Datenbankprogrammierung 6
R Resultset.last() Problem Datenbankprogrammierung 12
PaulG Leeres ResultSet initialisieren Datenbankprogrammierung 6
J Frage zu ResultSet Datenbankprogrammierung 3
J SQL ResultSet Previous Datenbankprogrammierung 10
S MySQL ResultSet in ein Array übertragen Datenbankprogrammierung 7
H PostgreSQL Objekte aus ResultSet Datenbankprogrammierung 5
H ResultSet is closed tritt bei JSF aber nicht bei einer Java-Applikation auf Datenbankprogrammierung 10
O Oracle Resultset greift auf Spaltenüberschriften zu Datenbankprogrammierung 2
Kenan89 Wieso klappt das ResultSet nicht? Datenbankprogrammierung 3
C ResultSet enthält nicht alle Daten Datenbankprogrammierung 4
F Derby/JavaDB Resultset in JTablemodel Datenbankprogrammierung 2
F Oracle ResultSet zu einer HashMap<Integer, String[]> Datenbankprogrammierung 6
B SQLite ResultSet is TYPE_FORWARD_ONLY Datenbankprogrammierung 5
T Exception ResultSet Datenbankprogrammierung 7
0 ResultSet in JTable Datenbankprogrammierung 14
S [SQL] ResultSet Datenbankprogrammierung 4
R ResultSet Datenbankprogrammierung 4
I Sonderbehandlung wenn ResultSet leer ist Datenbankprogrammierung 9
I Problem mit ResultSet Datenbankprogrammierung 2
I SQL_Abfrage-Ergebnis (ResultSet) in String[] speichern Datenbankprogrammierung 29
B ResultSet wirft komische NullPointerException. Datenbankprogrammierung 3
R Detached ResultSet Datenbankprogrammierung 3
F generelle Vorgehensweise ResultSet Datenbankprogrammierung 5
S ResultSet Datenbankprogrammierung 2
A MySQL ResultSet.updateBytes schlägt fehl Datenbankprogrammierung 2
F ResultSet kann Datenbank nicht update, warum? Datenbankprogrammierung 3
T ResultSet befehl für leere Spalte nicht lesen Datenbankprogrammierung 4
S ResultSet einer Datenbankabfrage - Nullpointer Exception Datenbankprogrammierung 13
A PostgreSQL anfängerfrage: resultset zeilenweise auslesen Datenbankprogrammierung 2
T MySQL ResultSet zurückgeben nachdem Connection geschlossen wurde? Datenbankprogrammierung 3
K Keine ResultSet bei if in StoredProcedure Datenbankprogrammierung 16
D ResultSet gibt nichts aus. Datenbankprogrammierung 3
trash ResultSet Syntax Fehler Datenbankprogrammierung 11
ARadauer JDBC ResultSet schließen? Datenbankprogrammierung 4
M Oracle Problem mit Resultset Datenbankprogrammierung 11
J jdbc ResultSet types Datenbankprogrammierung 5
R Frage zu PreparedStatement/ResultSet Datenbankprogrammierung 16
F ResultSet to String[] Datenbankprogrammierung 3
E ResultSet in HashMap Datenbankprogrammierung 8
K Tabelle mit resultset refreshen? Datenbankprogrammierung 4
M Problem mit ResultSet bei SQL Server 2005 Datenbankprogrammierung 6
S ResultSet in ArrayList ablegen Datenbankprogrammierung 17
G Daten aus ResultSet in String-Liste Datenbankprogrammierung 13
T ResultSet initialisieren Datenbankprogrammierung 2
C kein Resultset Datenbankprogrammierung 2
G ResultSet: String mit Anführungszeichen einlesen Datenbankprogrammierung 8
T ResultSet-Inhalt in Arrays schreiben Datenbankprogrammierung 3
S ResultSet variabel auslesen Datenbankprogrammierung 4
D Anzahl der Elemente im ResultSet ermitteln Datenbankprogrammierung 8
A Leeres ResultSet mit H2 unter Vista Datenbankprogrammierung 3
A Warum ist mein ResultSet leer? Datenbankprogrammierung 5
S ResultSet closed Datenbankprogrammierung 2
Z ResultSet mit einer anderen Datenquelle Datenbankprogrammierung 7
O Spaltenname aus Resultset Datenbankprogrammierung 2
thE_29 ResultSet und doppelte Spalten Datenbankprogrammierung 4
E Neues select auf ein vorhandenes Resultset Datenbankprogrammierung 11
E ResultSet vergisst Reihe? Datenbankprogrammierung 2
N resultset aus andere klasse übergeben Datenbankprogrammierung 3
F ResultSet refresh moeglich? Datenbankprogrammierung 3
S ResultSet enthält keine Daten Datenbankprogrammierung 2
B Geschlossenes ResultSet Datenbankprogrammierung 6
T ResultSet#next Ungültige Reihenfolge (DB2) Datenbankprogrammierung 5
T ResultSet schließen? Datenbankprogrammierung 6
S Tabelle updaten wenn ResultSet aus JDBC-Quelle Datenbankprogrammierung 2
S ResultSet Datenbankprogrammierung 6
F Filtern innerhalb eines Resultset Datenbankprogrammierung 12
S Connection/Statement/ResultSet auf einmal geschlossen Datenbankprogrammierung 8
@ Like-Klausel; NPE bzw. leeres ResultSet Datenbankprogrammierung 4
C Resultset nach connection close weiterreichen Datenbankprogrammierung 5
B No ResultSet was produced Datenbankprogrammierung 2
S ResultSet erweitern ? Datenbankprogrammierung 4
E JDBC, ForwardOnly bei ResultSet nach Uebergabe Datenbankprogrammierung 4
R ResultSet liefert oracle.sql.TIMESTAMP, aber unbrauchbar Datenbankprogrammierung 9
A Probleme mit ResultSet und getString(i) Datenbankprogrammierung 13
RaoulDuke ResultSet - Wie arbeitet sowas intern Datenbankprogrammierung 2
N Probleme mit "nur vorwärts gerichtete ResultSet" Datenbankprogrammierung 7
G Für jede SQL-Abfrage eigenes Statement und ResultSet? Datenbankprogrammierung 3
T MAX und ResultSet#next Datenbankprogrammierung 10
R ResultSet zu bestimmtem DS navigieren Datenbankprogrammierung 4
S .leeres Resultset abfangen Datenbankprogrammierung 2

Ähnliche Java Themen

Neue Themen


Oben