Lesen vieler Zeilen aus DB
-
Hab gestern abend noch ein Problemchen entdeckt und jetzt ein WE zeit drüber nachzudenken ... Vielleicht hilft mir ja jemand von Euch dabei
Ich stelle hintereinander drei etwas aufwändigere DB-Abfragen. Die Abfragen an sich sind mit Ablaufplan optimiert worden und dauern jeweils ne knappe Sekunde. Die Ergebnismenge ist jeweils im 5-Stelligen Bereich.
Jetzt hab ich festgestellt, dass allein das iterieren über eine Ergebnismenge vielleicht 30 sec dauert. D.h. ich hab das Lesen völlig auskommentiert und mach nur noch
while( SQLfetch( stmt)) {/*hier alles auskommentiert*/}
Für die drei Anfragen brauch ich so schon allein 1 1/2 Minuten - und das ist viel zu lang.
Frage 1:
Hab da nur ein bisschen Halbwissen: Ist es nicht so, dass, wenn man ein Statement ausführt schon Ergebnisse geliefert werden, wenn die Datenbank noch garnicht alle Ergebnisse hat? Sucht die DB noch nach Ergebnissen, während ich schon über die ersten Ergebnisse iteriere und muss dann öfter mal warten - weil das iterieren in der Applikation schneller ist als das Suchen in der DB?
Wenn das so wäre könnte ich die drei Statements doch direkt hintereinander absetzen und die Daten von Abfrage 2 und 3 würden schon geladen, während ich noch über das Ergebnis von 1 iteriere.
Ist das so? Ich hab da wie gesagt nur Halbwissen ...Frage 2:
Die Datenbank wird per ODBC angesprochen. ODBC soll ja recht lahm sein. Könnte da die Umstellung auf was anderes deutlichen Performance-Gewinn bringen? Was könntet Ihr empfehlen (C/C++ mit Oracle)Frage 3:
Könnte das Parallelisieren der drei Abfragen was bringen? Ich schätz das kann man nichs so genau sagen und muss es probieren ...
-
Zu Frage 1: Ich schätze das ist DB-Abhängig. Bei Datenbanken wie MySql, die ja auch die Anzahl der Zeilen liefern, können die das logischerweise erst, wenn sie das komplette Result-Set durchgenudelt haben wissen. Vermute ich zumindest. Bei anderen Datenbanken, die bei SELECT keine Zeilenanzahl liefern wird in der Tat geliefert bevor das Statement komplett abgearbeitet ist (ist z.B. bei DB2 definitiv der Fall).
Frage 2: Ich exportiere Tabellen aus einer DB2-Datenbank-Tabelle in eine Dbase-Tabelle. Per ODBC-API (=DB2-CLI): Über 100.000 Datensätze/Sekunde. Wenn ich das Schreiben der Dbase-Tabelle auskommentiere über 300.000 Datensätze/Sekunde. Ich würde daher mal sagen, ODBC ist schnell genug.
Frage 3: Keine Ahnung
-
Wenn du nicht alle Ergebnisse auf einmal brauchst, könntest du theoretisch immer nur eine gewisse Anzahl der Daten laden und das ganze so in kleinere häppchen aufteilen.
-
Frage 2: Ich exportiere Tabellen aus einer DB2-Datenbank-Tabelle in eine Dbase-Tabelle. Per ODBC-API (=DB2-CLI): Über 100.000 Datensätze/Sekunde. Wenn ich das Schreiben der Dbase-Tabelle auskommentiere über 300.000 Datensätze/Sekunde. Ich würde daher mal sagen, ODBC ist schnell genug.
hm, da frag ich mich schon, warum bei mir lächerliche 40 000 Datensätze so ein Problem sind. Exportierst Du einfach die gesamte Tabelle (ohne where-clause) oder ist da irgendwas komplizierteres bei?
Abgesehen davon: so kompliziert sind meine Abfragen eigentlich garnicht:
Ich hab vor den drei besagten Abfragen ne teure Abfrage, die als Ergebnis IDs in ner temporären Tabelle ablegt. Die besagten drei Abfragen machen dann sowas:
select * from tabelle_1 where indizierte_spalte in ( select * from tempIds);
select * from tabelle_2 where indizierte_spalte in ( select * from tempIds);
select * from tabelle_3 where indizierte_spalte in ( select * from tempIds);In tempIds stehen 20 000 Datensätze. Die Ergebnisgröße der Abfragen ist auch so groß oder größer.
Wenn du nicht alle Ergebnisse auf einmal brauchst, könntest du theoretisch immer nur eine gewisse Anzahl der Daten laden und das ganze so in kleinere häppchen aufteilen.
Die Reihenfolge in der ich lese ist mir egal. Am Ende muss ich aber alle gelesen haben. Wär also auch ne Idee. Wenn ich nur weiß, dass es bei Oracle überhaupt was bring. Wo find ich raus, wie Oracle die Ergebnisse liefert? (ich mein ich kanns am Montag ausprobieren. Aber je früher ich es sicher weiß, desto beruhigter ist mein WE )
-
doppelposting
-
Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum Datenbanken verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Die Statements hintereinander absetzen und dann zu iterieren bringt erstmal nix.
Nochmal ne Frage:
Es sind ja eigentlich nicht sooo viele Datensätze, die ich kriege. Dafür dauert das ganze doch eigentlich viel zu lang. Zugleich ist während des Iterierens die Prozessorauslastung auf dem Clientrechner nicht 100%. Gibt es vielleicht irgendne Puffer-Größe in der ein Teil der Ergebnismenge an den Client übergeben wird und der erst wieder aufgefüllt wird, wenn der Client alle Daten aus diesem Puffer gelesen hat???