Asynchrone Datenbankabfarge SQLite!?



  • Hallo Leute,

    hier mal ne ganz "blöde" Frage, gibts es ne möglichkleit eine Query Asynchron abzufragen!? Prinzipiell ist das ja nicht möglich, da ja die DB je nach SQL Statement die Daten erst alles lesen musst, umd sie evtl. noch zu sortierren etc.

    Aber wenn ich einfach nur die Daten von oben nach unten lesen möchte und ich die Datensätze so asynchron lesen (wie sie abgelegt wurden).

    Gäbe es so ne Möglihckeit, oder soll ich das ganz schnell wieder vergessen!?;)

    Grüße



  • NullbockException schrieb:

    Aber wenn ich einfach nur die Daten von oben nach unten lesen möchte und ich die Datensätze so asynchron lesen (wie sie abgelegt wurden).

    Das Wort "asynchron" macht in dem Satz keinen Sinn.

    Du kannst Daten unsortiert abfragen, dann sortiert sie SQLite auch nicht. Du kannst nur ein paar Datensätze lesen, dann liest SQLite auch nicht alle von der Disk (es sei denn er muss, weil er z.B. sortieren muss oder was anderes machen was er nur kann nachdem er erstmal alles gelesen hat).
    Und du kannst das ganze in einen eigenen Fred packen, dann ist es auch "asynchron".

    Und jetzt sag bitte nochmal was du eigentlich willst.



  • Ich verwende einen SQLReader, auder mich in einer schleife datensatz für datensatz lese! Allerdings beginnt dieser prozess erst nach einigen sekunden, nach dem der querycommand ExecuteCommand abgesetzt wurde, da wohl die db engine die daten erst rauholt in speicher, und dann mit über den reader ausgibt.

    wenn ich nun 500T datensätze habe, würde ich gern schon diersten 1000 lesen, bevor die query alles durchlaufen hat, so dass ich da keine warte zeiten habe.

    zudem is mir aufgefallen, dass eine SQLite query ab und an "sehr viel länger braucht" bevor sie einmal ausgeführt wurde.. das ding cached die daten wohl.. aber welche strategie dahinter steckt weiß ich nicht.

    spricht, meine query brauchst erst mal 5-7 sek bevor die rsten datenstätze aus der dem reader kommen.. und das würde ich gern parallelisieren, die datensätze müsse nauch nich sortiert kommen.. hauptsache "parallel" bzw. asynchron..

    Grüße



  • Bitte verwende hier nicht das Wort asynchron, asynchron bedeutet ganz was anderes.

    Und zeig mal deine Query.
    Und was für ein SQLReader? Verwendest du C# oder was?

    SQLite ist eine C-Library, da gibt es keinen SQLReader.



  • Wie nennt man es dann parallel, simultan!?

    ja vewrendet c#!

    using (var sqlCmd = _connection.CreateCommand())
    			{
    				var sqlText = "SELECT TimeStamp, TypeID, EntityID, CurrentData FROM " + _partitionName
    					+ " WHERE TimeStamp <= '" + to.Ticks + "' ORDER BY TimeStamp ASC;";
    
    				sqlCmd.CommandText = sqlText;using (var reader = sqlCmd.ExecuteReader())
    			{
    				bool cancel = false;
    				while (reader.Read() && !cancel)
    				{
    					cancel = delRecord(new BinaryRecord()
    							{
    								TimeStamp = new DateTime(reader.GetInt64(0)),
    								Data = (byte[])reader.GetValue(3),
    								TypeId = reader.GetInt32(1),
    								EntityId = reader.GetInt32(2)
    							});
    				}
    
    				reader.Close();
    			}
    }
    

    hier der code....



  • Wie Dir schon gesagt wurde MUSS die Datenbank, um nach Timestamp zu sortieren, erst alle Datensätze in den Speicher holen.



  • "asynchron" ist in dem Zusammenhang IMHO gar ned so verkehrt 🙂

    Momentan arbeitest du synchron (1 thread)
    ob jetzt Assynchronitaet (multithreading, multiprozessing, implizietes multiprozessing (assynchrone funktionen vom BS)) so weiterhilft, iss ne andere Frage ...

    wie LordJaxom schon andeutet, Abfrage selber beschleunigen ohne funktionalitaetsverlust wird vielleicht nicht so ohne weiteres moeglich sein ....

    was ist timestamp fuer nen Typ ?
    schon mal versucht nen Index auf den timestamp zu legen
    Dan wird das einfuegen langsammer, aber das sortierte auslesen sollt schneller gehen ...

    Mit assynchronitaet wurdest hinbekommen, das deine GUI waehrend der Abfrage nicht blockiert. Damit wird die abfrage nicht schneller, es fuehlt sich meistens aber flotter an ^^

    DU kannst das sortieren aber selber auch noch optimieren ... sql nutzt immer ziemlich generische Verfahren ...
    unsortiert auslesen, daten in geeignete Datentypen wandeln (nicht String Typ), und dann geeignetes sortierverfahren wählen und selber sortieren, koennte den prozess nochmal richtig beschleunigen ...

    Ciao ...



  • @RHBaum
    Er will aber nicht asynchron, er will "fast first row".
    Und ja, Index auf TimeStamp wird hier Wunder wirken.

    NullbockException schrieb:

    Aber wenn ich einfach nur die Daten von oben nach unten lesen möchte und ich die Datensätze so asynchron lesen (wie sie abgelegt wurden).

    Gäbe es so ne Möglihckeit, oder soll ich das ganz schnell wieder vergessen!?;)

    Ja, es gäbe da die Möglichkeit das "ORDER BY" wegzulassen 🙄



  • hustbaer schrieb:

    Ja, es gäbe da die Möglichkeit das "ORDER BY" wegzulassen 🙄

    Ich bezweifel, dass ein SELECT ohne ORDER BY stets die Reihenfolge liefert "wie sie abgelegt wurden".



  • Wenn der Primärschlüssel aufsteigend ist, dann kannst du auch ein Order By auf diesen machen. Der ist zumindest schon ein Index.



  • Jockelx schrieb:

    hustbaer schrieb:

    Ja, es gäbe da die Möglichkeit das "ORDER BY" wegzulassen 🙄

    Ich bezweifel, dass ein SELECT ohne ORDER BY stets die Reihenfolge liefert "wie sie abgelegt wurden".

    Ja eh aber darum gehts ihm ja nicht.
    Er will doch bloss dass das Ergebnis nicht dadurch verzögert wird dass der SQLite sortieren muss. Und das erreicht er in diesem Fall in dem er einfach das ORDER BY weglässt.



  • ich vermute, dass er außerdem auch noch möchte, dass nicht alle datensätze auf einmal übertragen werden müssen.

    also, wenn er insgesamt 500T datensätze ausliest, dann soll die ausgabe schon starten, wenn 1000 empfangen wurden.

    ich kenne da nur die möglichkeit, dass man die query entsprechend formuliert, dass sie immer nur häppchen liefert.



  • @jenz
    Er.
    SQLite ist eine Library, da wird gar nichts übertragen.

    Und ich kenne das (bei Client/Server Systemen) nur so, dass das "häppchenweise" automatisch ohne irgendwelche speziellen Optionen/... passiert - so bald sich die Query halt dafür eignet.



  • hm, dann muss ich umformulieren.

    ich kenne die lib jetzt nicht genau.
    aber ich vermute, dass man eine query öffnen kann.
    nach dem öffnen stehen dann sofort alle 500T einträge zur verfügung.
    das öffnen hat die 500T einträge also alle zusammengesammelt und kehrt erst dann zurück.

    dabei wäre nach 1000 einträgen zurückzukehren viel früher passiert.

    deshalb wahrscheinlich auch die formulierung asynchrone datenbankabfrage...
    das macht da nämlich schon sinn.

    j



  • jenz schrieb:

    hm, dann muss ich umformulieren.

    ich kenne die lib jetzt nicht genau.

    du kennst anscheinend nicht wirklich viele DB libs... ?

    aber ich vermute, dass man eine query öffnen kann.

    bis hierher noch korrekt.

    nach dem öffnen stehen dann sofort alle 500T einträge zur verfügung.
    das öffnen hat die 500T einträge also alle zusammengesammelt und kehrt erst dann zurück.

    nein und nein.
    wäre mmn. auch ziemlich bekloppt das als einzige möglichkeit anzubieten.

    als ergebnis des "query öffnens" bekommst du nen cursor.
    den cursor kannst du lustig vor-/zurückspulen (bzw. forward-only cursor eben nur vor). und dann halt immer die werte der aktuellen zeile abfragen.

    das ist bei jedem datenbank-interface das ich kenne so, und auch bei SQLite. (manchmal gibt es hilfsfunktionen die gleich das ganze ergebnis einlesen und ein array o.ä. zurückgeben, aber die basis-funktionen sind eigentlich immer cursor-basiert.)

    deshalb wahrscheinlich auch die formulierung asynchrone datenbankabfrage...
    das macht da nämlich schon sinn.

    für mich macht das keinen sinn.
    die funktionen die er aufruft sind doch weiterhin immer synchron.
    und je nach datenbank/library läuft da auch im hintergrund nix asynchron.
    ne typische DBase library wird hier z.b. keine threads verwenden, sondern einfach beim "eine zeile vor" aufruf den nächsten datensatz lesen.



  • na dann wollte der gute bestimmt einfach einen hinweis auf cursor-funktionen.

    und ja, die cursor sind genau das richtige dafür.

    welche lib benutzt denn direkt einen cursor?
    bei mysql "C API Function Descriptions" transportiert mysql_stor_result zum beispiel auch alles auf einmal zum client.

    bei postgres macht es PQexec genauso.

    aber ich habe auch gesehen, dass es bei sqlite anders ist
    ich gehe dann mal in mich und ein wenig lesen

    j



  • > welche lib benutzt denn direkt einen cursor?

    ODBC, OLEDB, ADODB...
    mag sein dass das eine MS-eigenart ist.

    > bei mysql "C API Function Descriptions" transportiert mysql_stor_result zum beispiel auch alles auf einmal zum client.

    bei mysql kannst du mysql_use_result + mysql_fetch_row verwenden um zeilenweise zu lesen.

    ich meine auch dass fast jede API irgend eine möglichkeit dafür anbieten muss - sonst wäre es ja ziemlich doof wenn man grosse result-sets auf clients mit beschränktem RAM hat.
    oder eben fälle wie den des OP, wo das programm irgendwann entscheidet dass es die restlichen datensätze gar nicht mehr braucht.
    (idealerweise würde man die bedingung in die query mit einbauen, aber manchmal ist es effizienter bestimmte dinge in der applikation zu machen)


Anmelden zum Antworten