Datenbank in Java

Aloisia

Mitglied
Die Datenbank wurde angelegt mit
SQL:
CREATE TABLE Person (NUMBER int, PRIMARY KEY(NUMBER));
Die anderen Spalten habe ich nachträglich angelegt....

Ich suche immer nur nach WHERE NUMBER = <x> (Je nachdem welche Nummer ich haben will)
Trotzdem dauert es "ewig" wenn ich an bestimmten Stellen im Programm alle Personen laden muss.
Ich habe mir auch schon überlegt, die Daten beim Programmstart in ein Array zu laden, und von dort aus dann zu "verteilen", beim Ende des Programms dann das Array wieder in die Datenbank zu schreiben.
Nachteil aus meiner Sicht: Die Werte werden (z.B, bei Programmabstürzen) eventuell nicht geändert...
 

Improof

Erfahrenes Mitglied
Hi,

wenn du alle Personen laden musst, machst du dass dann mit dem gleichen Query? Also für jede Person ein SELECT * FROM Person WHERE NUMBER = <x> ??
Nur nochmal zur Verdeutlichung: Viele Selects sind natürlich langsamer als ein mal SELECT * FROM Person ohne WHERE. Den jeweiligen Index kannst du dann ja in deinem ResultSet auslesen.

Außerdem zur Begrifflichkeit: Du legst in diesem Fall keine Datenbank an, sondern eine Tabelle innerhalb deiner Datenbank.

Wenn du sagst "ewig", wie lange dauert es denn? Mach mal einen kleinen Test:

Java:
long start = System.currentTimeMillis();

// Dein Code, wo der SELECT gesendet wird

long end = System.currentTimeMillis();
long dt = end - start;
System.out.println("Vergangene Zeit: " + dt + " ms");

Ich hab nur vor Ewigkeiten mal was mit HSQLDB gemacht, sonst nur MySQL, Oracle. Und natürlich hast du bei deiner Variante wahrscheinlich ein bisschen Performance-Einbußen. Aber dennoch dürfte es nicht "ewig" dauern deine 300 Einträge zu laden. Ich habe teilweise schon Queries gegen eine DB geschickt, bei der 3 oder mehrere Tabellen mit jeweils mehr als 1 Million Einträgen verknüpft wurden, mit Sub-Selects usw. usw. und wenn da etwas ewig dauert, ja kann man verstehen. Aber bei 300 Einträgen kann ich mir das schlecht Vorstellen selbst bei HSQL...
(Als Beispiel: Musste kürzlich ein Update auf eine Tabelle mit ca. 100.000 Einträgen machen (was eigentlich gar nicht mal so viel ist, wie man meint). Die Updates waren von einer anderen ca. halb so großen Tabelle abhängig, also mit einem Select im Update. Insgesamt hat das dann so ca. 8 Sekunden gedauert, bis es durchlief und alle Einträge aktualisiert waren. Das ganze auf Oracle).
 

Aloisia

Mitglied
Hi,

wenn du alle Personen laden musst, machst du dass dann mit dem gleichen Query? Also für jede Person ein SELECT * FROM Person WHERE NUMBER = <x> ??
Ja, da ich das vorher alles in 'txt' Dateien (bzw. 1.person, 2.person,...) hatte.

Nur nochmal zur Verdeutlichung: Viele Selects sind natürlich langsamer als ein mal SELECT * FROM Person ohne WHERE. Den jeweiligen Index kannst du dann ja in deinem ResultSet auslesen.
Ja, ich glaube, ich sollte das eben umschreiben, dass nicht eine einzelne Zeile geladen wird, sondern die ganze Tabelle. Und dann auf das ResultSet zugegriffen wird.
Außerdem zur Begrifflichkeit: Du legst in diesem Fall keine Datenbank an, sondern eine Tabelle innerhalb deiner Datenbank.

Wenn du sagst "ewig", wie lange dauert es denn? Mach mal einen kleinen Test:

Java:
long start = System.currentTimeMillis();

// Dein Code, wo der SELECT gesendet wird

long end = System.currentTimeMillis();
long dt = end - start;
System.out.println("Vergangene Zeit: " + dt + " ms");
Vergangene Zeit: 53364 ms
 

sheel

I love Asm
54sec für 300 Zeilen? :eek:

Wenn das für dich ok ist, lad vllt. einmal das gesamte Projekt als Zip rauf.
Da hat man dann eher den Überblick
 

Aloisia

Mitglied
Ich habe das gleich in dem "großen Projekt" gemacht... ich werde dann das hochladen (nicht das "minimalbeispiel Person")
Geht das irgendwie, dass dann nur du Zugriff darauf hast?
 

Improof

Erfahrenes Mitglied
Vergangene Zeit: 53364 ms

Ähm...krass...viel mehr kann man da wirklich nicht dazu sagen :eek:o_O
Ok um das mal ein bisschen aufzudröseln: Zwischen den beiden System.currentTimeMillis(), was geschieht da alles? Kein Code, einfach eine Beschreibung. Was ich genau wissen möchte:
Ist da nur das SELECT * FROM Person ?? Oder ist da auch deine while-Schleife mit resultSet.next() usw. ?? Worauf ich hinaus will ist, dass es nicht die Datenbank, sondern evtl. deine Programmlogik hier ist, die so lange braucht. Ich denke darum hat sheel auch gemeint, dass er mal deinen Code als Überblick sehen will. Wenn es tatsächlich nur der SELECT ist, dann stimmt irgendwas mit deiner DB nicht..

Gruß
Daniel
 

Aloisia

Mitglied
Ok, so ein bisschen abstrakt:

Aufruf erfolgt:
schleife (i=1 bis 297)
Person p = Lade Person Nummer(i);

*SPRUNG IN PERSONKLASSE*

SELECT * FROM Person WHERE...
Person p;
if(resultSet.Next()){ //ABFRAGE ob "nicht NULL"
bla = resultSet.getString(2).trim();
bla1 = resultSet.getString(3).trim();
...
p= new Person(bla,bla1,..);
return p;
}

*SPRUNG ZURÜCK IN AUFRUFENDE KLASSE*
Prüfe ob Person p mehrere Vorraussetzungen erfüllt
if()...
case...
Wenn ja dann add zu einer LinkedList
Next i

Läuft deshalb so, weil ich bei den txt Dateien "sowieso" in die 2.,3.,4. Zeile schauen musste und so habe ich mir gedacht lieber erst Person erstellen, und dann prüfen => anhängen oder verwerfen.
Jetzt wäre es natürlich schlauer in der Abfrage SELECT gleich die Filter einzubauen und dann nur das benötigte resultSet zu laden (wenn ich sowieso fast alle lade...)

an anderer Stelle will ich jedoch 80 zufällig gewählte Personen laden (die auch die Voraussetzungen erfüllen)...
Da ich aber nicht weiß ob Nummer <x> die Voraussetzungen erfüllt bevor ich sie geladen habe werde ich ein ähnliches Problem haben.
 

Improof

Erfahrenes Mitglied
Hi,

du gehst doch noch die Personen in einer Liste durch und hast demnach fast 300 SELECTS...das ist auf jeden Fall dein primärer Punkt, die Performance zu verbessern (SELECT * FROM Person).
Die Filter mit den Bedingungen, ja, bitte gleich ins SELECT. Bevor du dann in Java alles überprüfst, wird es schneller gehen, dass der DB zu überlassen.

Bei deinen zufälligen Personen:
Du siehst, viele Queries machen dein Programm extrem langsam. Es kann sein - besser gesagt: es wird höchstwahrscheinlich so sein, dass es schneller geht, wenn du (wie oben) immer alle Personen lädst. Klar, wenn du nur 1 oder 2 aus 300 brauchst, dann lad eben nur diese. Aber bei 80 lade alle, mit dem eingebauten WHERE mit deinen Voraussetzungen, da das ja wie gesagt auf DB Ebene schneller geht.

Und dann wähle in Java zufällig 80 von den geladenen aus. Ich weiß, es hört sich komisch an, Personen zu laden, die du dann gar nicht verwendest, aber bei deinen 300 bzw. mit den Voraussetzungen ja noch weniger => Mach es einfach so. Vorher zufällige Nummern zu erzeugen und dann für jede Nummer einen Person laden und erst Java-seitig testen, ob sie verwendet wird oder nicht - eher schlecht.

Gruß
Daniel