Problem mit Datenbankdesign

Okilidokili :slight_smile:

Ich muss schon wieder stören. Mein neues Datenbankkonzept ist soweit implementiert, und die Datensätze werden erfolgreich eingelesen. Probleme macht nun allerdings das Auslesen. Beim Ausgeben der Suchergebnisse sollen diese in einer bestimmten Reihenfolge geordnet werden - per SQL ansich kein Problem.

Allerdings kombiniere ich dabei die vorhin vorgeschlagenen JOINS (genauer gesagt NATURAL JOIN) und ORDER BY, was leider total in die Hose geht, weil das Programm undefinierbar lange braucht um die Datensätze zu ordnen. Nur hab ich leider nicht die geringste Ahnung wieso?

Hier der SQL-Befehl: [sql]SELECT * FROM
tbl_files NATURAL JOIN tbl_industries NATURAL JOIN tbl_clients NATURAL JOIN tbl_workpieces NATURAL JOIN tbl_machines
WHERE […]
ORDER BY industry,client,workpiece,lang,file_index;[/sql]
Die Spalten industry, client, und workpiece befinden sich nicht in tbl_files sondern in den jeweiligen gejointen Tabellen als String-Werte.

Mache ich vlt. etwas beim JOINen falsch? Ich habe denselben Query mal ohne ORDER BY ausprobiert, und es dauert ebenfalls ewig. In meiner Datebank befinden sich vlt. gerade mal 9500 Datensätze oder so und das merkwürdige ist, dass er nicht zum Auslesen ewig braucht, sondern bereits zum Verarbeiten des Querys!

Naja, du machst einen NATURAL_JOIN über 4 Tabellen a 9500 Datensätze (wenn ich das richtig verstanden habe) ohne Bedingungen … was erwartest du?

Also 10k Einträge sollten eigentlich in Bruchteilen einer Sekunde kommen, sieh eher nach dass deine Spalten gut benannt sind.
Alternativ Natural-Join durch normalen Join + Where ersetzen, das ist schneller.

@EagleEye
Heißt genau? ?_?
Was meinst du mit „richtig benannt“?

Naja, du machst einen NATURAL_JOIN über 4 Tabellen a 9500 Datensätze (wenn ich das richtig verstanden habe) ohne Bedingungen … was erwartest du?

Natürlich mit Bedingungen, nur variieren die eben stark (der SQL-Query ist Autogeneriert aufgrund der Benutzereingaben) deswegen habe ich statt Bedingungen […] angegeben.

naja zb Tabelle 1 hat die Spalten tab1_id, name und Tabelle 2 hat tab2_id, name
machst du jetzt einen Natural Join dann Joint er über ID und Name, das kann das gleiche Ergebnis bringen aber es macht alles langsamer (Statt Name kannst du jetzt auch irgend eine andere Spalte sehen)

Und wenn ich doch einfach mit Subselects arbeite? Das sollte eigentlich schneller funktionieren.
Funktioniert Subselect kombiniert mit IN() ?

Ob du subselects oder joins benutzt ändert nicht sehr viel, da die Datenbanken das meistens schon umstellen.
Was hilft, mache normale Joins
also nicht [sql]SELECT * FROM tabelle1 NATURAL JOIN tabell2[/sql]
sondern[sql]SELECT * FROM tabelle1 t1, tabelle2 t2 WHERE t1.id=t2.tab1_id[/sql]
Das ist schneller als ein Natural Join

Okay, klingt soweit gut. Wie kann ich dann die Daten aus dem ResultSet auslesen? Auch mit rs.getString(“t1.feldname”) ?

jep aber du kannst die Spaltennamen auch neu benennen also t1.name AS tabelle100000name
und dann mit re.getString(“tabelle100000name”) oder res.getString(1) drauf zugreifen

Verstehe. Allerdings glaube ich, dass dein SQL-Code nicht ganz dasselbe macht als NATURAL JOIN.

Ich habe mal diesen SQL-Befehl getestet:
[sql]SELECT f.industry_id, f.file_index, f.client_id, f.workpiece_id, f.machine_id, f.media, f.conf, f.lang, f.extra, f.suffix
FROM tbl_files f, tbl_industries i, tbl_clients c, tbl_workpieces w, tbl_machines m
WHERE f.file_index=‘0002’ AND m.machine=‘M50’
LIMIT 500;[/sql]

Soweit so gut, nur die Bedingung m.machine=‘M50’ scheint ihn überhaupt nicht zu tangieren denn er gibt nur M30-Maschinen aus!

Natural Join erzeugt einen „normalen“ Join bei dem der Server selbstständig die Spaltennamen der Tabellen anhand der Namen verbindet.
D.h. er erzeugt automatisch Where Bedingungenfür Spalten die den gleichen Namen haben
Tabelle 1 (id, name, blub)
Tabelle 2 (id, name, blab)
→ Where t1.id = t2.id AND t1.name = t2.name;
Und genau das ist auch eine Fehlermöglichkeit, weil Name soll hier vielleicht nicht als Join genommen werden nur das fällt einem meistens erst zu spät auf :wink:

Ich hab das Ganze jetzt einmal mit Subselects versucht. Das Ergebnis: 1. funktioniert es wie gewünscht und zweitens läuft es auch noch bedeutend schneller. Dabei steht doch im Wiki dass JOINs schneller sind oO
Sind in SQLite die Subselects möglicherweise besonders optimiert bzw. die JOINs besonders schlecht implementiert?

[sql]SELECT industry_id, file_index, client_id, workpiece_id, machine_id, media, conf, lang, extra, suffix
FROM tbl_files
WHERE file_index=‘0002’ AND machine_id IN(SELECT machine_id FROM tbl_machines WHERE machine=‘M50’)
LIMIT 500;[/sql]

Mein einziges Problem ist jetzt noch das Sortieren. Ich muss nämlich alphabetisch Sortieren (mit Werten aus andern Tabellen) und da helfen mir die Secondard-IDs leider wenig …

Ob Joins schneller oder langsamer sind kann man nicht sagen das hängt immer von der Anwendung ab. Die großen Datenbanken ändern das auch selbstständig um, das sieht man gut bei Postgres. Schickst du nen Subquery hab macht er da teilweise nen Join draus und umgekehrt.
Aber ich glaub Joins werden häufiger verwendet, gerade bei deiner Abfrage da müssten die eigentlich schneller sein.

Ich hab jetzt noch etwas gegoogelt und bin (hoffe ich) endlich zu einer zufriedenstellenden Lösung gekommen:
[sql]SELECT i.shortform, f.file_index, c.client, w.workpiece, m.machine, f.media, f.conf, f.lang, f.extra, f.suffix
FROM tbl_files f
JOIN tbl_industries i ON (f.industry_id=i.industry_id)
JOIN tbl_clients c ON (f.client_id=c.client_id)
JOIN tbl_workpieces w ON (f.workpiece_id=w.workpiece_id)
JOIN tbl_machines m ON (f.machine_id=m.machine_id)
WHERE f.file_index=‚0002‘ AND m.machine=‚M50‘
LIMIT 500;[/sql]

Diese JOIN-ON Kombination hatte ich schon wieder ganz vergessen. Ich war wohl zu sehr auf diesen NATURAL JOIN fixiert ^^
Dieser JOIN funktioniert übrigens tatsächlich schneller als die SUBSELECT-Variante :slight_smile:

An dieser Stelle herzlichen Dank für alle eure Tipps und Ratschläge! :smiley:

genau das ist die schöne Version :wink:
Ja ich denke dass es unteranderem daran liegt, hier muss der Server nicht alle Tabellen durchgehen und vergleichen wo die Namen gleich sind. Bestimmt kommen da noch andere Sachen dazu.

[QUOTE=EagleEye]Ob du subselects oder joins benutzt ändert nicht sehr viel, da die Datenbanken das meistens schon umstellen.
Was hilft, mache normale Joins
also nicht [sql]SELECT * FROM tabelle1 NATURAL JOIN tabell2[/sql]
sondern[sql]SELECT * FROM tabelle1 t1, tabelle2 t2 WHERE t1.id=t2.tab1_id[/sql]
Das ist schneller als ein Natural Join[/QUOTE]

Igitt, Kreuzprodukte … und sowas bezeichnest du als „normal“ :smiley: ?

[QUOTE=christoph;9723]Ich hab jetzt noch etwas gegoogelt und bin (hoffe ich) endlich zu einer zufriedenstellenden Lösung gekommen:
[sql]SELECT i.shortform, f.file_index, c.client, w.workpiece, m.machine, f.media, f.conf, f.lang, f.extra, f.suffix
FROM tbl_files f
JOIN tbl_industries i ON (f.industry_id=i.industry_id)
JOIN tbl_clients c ON (f.client_id=c.client_id)
JOIN tbl_workpieces w ON (f.workpiece_id=w.workpiece_id)
JOIN tbl_machines m ON (f.machine_id=m.machine_id)
WHERE f.file_index=‚0002‘ AND m.machine=‚M50‘
LIMIT 500;[/sql]

Diese JOIN-ON Kombination hatte ich schon wieder ganz vergessen. Ich war wohl zu sehr auf diesen NATURAL JOIN fixiert ^^
Dieser JOIN funktioniert übrigens tatsächlich schneller als die SUBSELECT-Variante :slight_smile:

An dieser Stelle herzlichen Dank für alle eure Tipps und Ratschläge! :D[/QUOTE]

Warum werd ich immer ignoriert? Liegt es daran, weil ich so klein bin und Eagle so groß ist :frowning: ?

:stuck_out_tongue_winking_eye:

du wurdest halt auf Null gesetzt :D:D:D

OK, ich geb mich geschlagen. Der war richtig gut :smiley: