Wie bekomme ich eine bestehende sqlite.db ins memory?

  • Hallo zusammen,

    ich habe eineSQlite DB mit 500000 Datensätzen in 2 Tabellen. Die DB habe ich auf FP. Bei Abfragen dauert es sehr lange, bis das Ergebnis da ist und die FP-Kontrolle leuchtet(blinkt) während der Abfrage. Ergo, die DB wird auf der FP abgefragt. Die 200 MB muß man doch irgendwie ins Memory bekommen? :memory: öffnet zwar eine Datenbank im Memory, aber darin sind dann nicht meine Daten.
    Kann ich die vorhandene DB irgendwie in eine Memory-DB übernehmen/ wandeln?
    Was hab ich als SQL-Befehl übersehen oder mißverstanden?

    Kann leider erst morgen antworten.

    Beste Grüße in die Runde,

    Trubadour

    Einmal editiert, zuletzt von Trubadour (15. Januar 2014 um 19:26)

  • Naja du könntest bei jedem Programmstart mit einer "frischen" memory db arbeiten und jedesmal einmalig alle Tabellen und Datensätze der HDD db in diese per SQL übertragen und zum Programmende wieder zurück transferieren. Ob das letzlich dann für dich aus Performancesicht noch lohend ist ist wieder ein anderes Thema, denn die Übertragung der kompletten Datei dürfte einiges an Zeit beanspruchen.

    Ein anderer Ansatz wäre eine reale RamDisk in die du bei Programmstart die DB Datei kopierst und dann von dort öffnest / bearbeitest und dann bei Porgrammende wieder zurück auf die HDD kopierst. Für eine RamDisk bist du aber soweit ich weiß auf Drittanbieter SW angewiesen, das wäre also nur eine Lösung wenn das Programm nur auf Rechnern genutzt wird die du selbst kontrollierst.

    Ebenfalls interessant wäre dein Programmcode. Vielleicht ist es garnicht wegen der Festplatte so langsam, sondern weil du unnötig viele Einzelabfragen machst die du auch über eine Transaktion zusammenfassend ausführen könntest. Siehe dazu auch meinen Thread in dem mich Bugfix genau auf diesen Fehler aufmerksam gemacht hat: https://autoit.de/index.php?page…8387#post328387

  • Hi und danke für die Antwort.

    und jedesmal einmalig alle Tabellen und Datensätze der HDD db in diese per SQL übertragen und zum Programmende wieder zurück transferieren

    Genau daran bin ja gescheitert. Wie kann ich das realisieren?

    Ebenfalls interessant wäre dein Programmcode. Vielleicht ist es garnicht wegen der Festplatte so langsam, sondern weil du unnötig viele Einzelabfragen machst die du auch über eine Transaktion zusammenfassend ausführen könntest.

    Ich mache momentan genau eine Abfrage, aber es könnten schon mehr als die Hälfte aller Datensätze als Antwort kommen. Es geht um die Klassifikation von Lebewesen. Und wenn man sich da von Reich bis Art durchklickten möchte, sind schon eine Menge Abfragen hintereinander nötig. Aber wenn die alle mehrere Sekunden dauern, ist dieser Datenbankansatz der falsche.

  • Ich hab dazu mal eine UDF gefunden die eine SQLite-Datenbank sicher Kopiert, auch in eine :memory: wenn gewünscht.
    Ich schaue mal ob ich die UDF bzw. den Namen der UDF finde wenn ich wieder am heimischen PC bin.

  • Um überhaupt Richtung NoSQL zu denken müsste man wenigstens grundlegende Informationen über die Struktur der Daten und die zu bewältigenden Abfragen vorliegen haben.

    Trubadour
    Zeige doch einmal wie die Daten in der Datenbank strukturiert sind und mit welchem Code du die Daten wie auswertest.
    Dann kann man vielleicht helfen.

  • Hi,

    Skerg

    Über die UDF oder den link zu selbiger würde ich mich sehr freuen.

    i2c

    Dann müßte ich ja wieder riesige txt-Dateien in Arrays einlesen. Ich denke schon, dass gerade für Abfragen SQL optimal ist. Nur kann ich ich nicht vertehen, wieso man nicht simpel die DB ins RAM kopieren kann. Dann wäre ich an der Sonne.


    AspirinJunkie

    Ich habe momentan 6 Tabellen in der DB (es werden aber mal mehr (womöglich aber in einer weiteren DB)) , die 31, 30 und 4 mal 2 Spalten haben. Die beiden erstgenannten Tabellen haben jeweils die gleiche Anzahl an Datensätzen. Verknüpft sind alle Tabs über eine gemeinsame Nummer.
    Habe ich also z.B. Pilz XY ausgewählt, kenne ich seine Nummer, unter der ich weitere Infos oder zukünftige Messwerte in den anderen Tabellen abfragen kann.

    [autoit]

    ##include <SQLite.au3>
    #include <SQLite.dll.au3>

    [/autoit][autoit][/autoit][autoit]

    Local $filedb,$aResult, $iRows, $iColumns, $SQL_Abfrage, $aRow

    [/autoit][autoit][/autoit][autoit]

    _SQLite_Startup()
    $filedb = _SQLite_Open(@ScriptDir&"\Life.db")
    _SQLite_GetTable2d($filedb, "SELECT * FROM tbl_klassifikation WHERE Genus = 'Agaricus' Group by Species", $aResult, $iRows, $iColumns)
    $SQL_Abfrage ='SELECT Max (id) FROM tbl_allgemein' ;Höchte Autoincrement - Nummer
    _SQLite_QuerySingleRow($filedb,$SQL_Abfrage, $aRow)
    MsgBox(0, "Wieviele", "Höchste MB-Nummer = "&$aRow[0]& " Anz. gefundener = " & $iRows)
    _SQLite_Display2DResult($aResult)
    _SQLite_Close($filedb)
    _SQLite_Shutdown()

    [/autoit]
  • Erstelle mal einen Index für tbl_klassifikation.Genus und für tbl_allgemein.ID.
    Vielleicht könnte auch ein zusammengesetzter Index für tbl_klassifikation.Genus und tbl_klassifikation.Species etwas bringen.
    Bisschen mehr Informationen zur Queryoptimierung kannst du erhalten wenn du vor das SELECT ein "EXPLAIN" schreibst.

    Achso: Zum Thema existierende HDD-DB in Memory: Spontan ohne es zu testen würde ich sagen: Neue Memory-DB in SQLite erstellen und die File-DB per "ATTACH DATABASE" in die Memory-DB übertragen.

    2 Mal editiert, zuletzt von AspirinJunkie (13. Januar 2014 um 23:02)

  • @AspirinJunkie

    Das hört sich nach guten Ansätzen an.
    Vielen Dank dafür.
    Ich muß jetzt erstmal recherchieren, ob Indices die Abfragen beschleunigen(und wie ich die dann benutze/ abfrage) und ob ATTACH die DB wirklich ins RAM schiebt.
    Meine DB-Abfrage war nur ein Beispiel. In Echt bräuchte ich wohl mehrere zusammengesetzte Indices.

    Zum Befüllen von ListViews zur Laufzeit muß es einfach viel schneller werden und ich merke immer mehr, dass ich zu wenig Ahnung von DBs habe... :(

  • Hi,

    hab ATTACH DATABASE und _SQLIte_backup.au3 ausprobiert. Danke an dieser Stelle für den link. Bringt aber alles irgendwie keinen fühlbaren Geschwindigkeitsgewinn. Warum auch immer?
    Ich werde mich jetzt in die Erstellung von Inidices einarbeiten und von Querys.
    Wie speicher ich denn Indices in der DB?
    Kann man Querys wieder weiter abfragen?

  • Du erzeugst mit "Create Index" ein Query? Ich dachte, ein Query ist eine Teilmenge der DB?

    Zitat von »Trubadour«

    Kann man Querys wieder weiter abfragen?


    Ich verstehe nicht was du damit ausdrücken möchtest.

    Wenn ich mit _SQLite_Query eine Teilmenge der DB erzeuge, kann ich diese wieder wie eine DB-Tabelle weiterbenutzen? Oder: wie schaffe ich es, kleinere Teilmengen der DB für weitere Abfragen vorzuhalten, damit nicht bei weiteren Abfragen immer die ganze Tabelle abgearbeitet werden muß?
    Und vielen Dank für den ersten Teil deiner Antwort.

  • Du erzeugst mit "Create Index" ein Query?
    Ich dachte, ein Query ist eine Teilmenge der DB?

    Sorry verschrieben - meinte natürlich einen Index mit "Create Index" erzeugen.
    Eine Query ist nichts weiter als eine Abfrage - also wenn du einen SQL-Befehl an die Datenbank schickst.
    Wenn das z.B. ein Select-Befehl ist bekommst du ein Ergebnis zurück - das ist sicherlich dass was du als Untermenge verstehst.
    Aber ein Query selbst ist nur ein Befehl den du an die Datenbank schickst.

    Wenn ich mit _SQLite_Query eine Teilmenge der DB erzeuge, kann ich diese wieder wie eine DB-Tabelle weiterbenutzen?

    Ja kannst du mit temporären Tabellen.
    Die kannst du erstellen und als Inhalt das Ergebnis einer SELECT-Abfrage eintragen.
    Ab diesem Moment kannst du die Tabelle dann wie jede andere Tabelle auch behandeln.
    Wenn du die Datenbank schließt verschwindet auch diese temporäre Tabelle wieder.
    Erstellen kannst du eine solche Tabelle mit folgender Syntax:

    SQL
    CREATE TEMP TABLE irgendeinname AS SELECT * FROM tabelle ...
  • Hi Aspirinjunkie,

    vielen Dank für die Aufklärung!
    Werde es jetzt mal mit Indices und Temp Tabellen versuchen, zu beschleunigen.
    Jedenfalls führt der Weg über :memory: , bzw. RAM DB zu keiner nennenswerten Beschleunigung auf meinem Laptop.