2012-11-15 6 views
5

Ich habe eine Anwendung auf Embedded Linux ausgeführt. Ich habe eine vordefinierte DB mit einigen Tabellen, wo jeder eine Menge Zeilen (Tausende) und 52 Spalten hat. Ich baute die DB voraus, weil ich besorgt bin, dass ich, wenn ich 'INSERT' zur Laufzeit mache, eine Datenträgerfragmentierung machen werde, also stattdessen eine DB mit viel Müll 'INSERT' und zur Laufzeit erstellen Ich benutze 'UPDATE's.SQLite WAL Leistungsverbesserung

Ich schreibe alle 3 Sekunden eine Menge Daten in die Datenbank. Und damit der Schreibvorgang schnell geht, benutze ich den WAL-Modus in SQLite. Obwohl ich ein Problem der Leistung habe. Es scheint, dass, wann immer ein Checkpoint auftritt, es zu lange dauert und der Prozessor es nicht in weniger als 3 Sekunden tun kann. Um dies zu verbessern, habe ich einen Thread, der nach wie 10 Schreib Anrufe, er eine Nachricht-Warteschlange von dem Haupt-Thread empfängt und als Checkpointing.

Jetzt scheint es, als wäre die Situation besser, aber die WAL-Datei wird immer größer und größer ... Wie kann ich hier arbeiten?

Antwort

5

Um Fragmentierung zu vermeiden und die Notwendigkeit, Daten vorzufü- gen, zu entfernen, sollten Sie sqlite3_file_control() mit SQLITE_FCNTL_CHUNK_SIZE verwenden, um die Chunk-Größe festzulegen. Wenn Sie den Speicherplatz für Datenbankdateien in großen Blöcken (z. B. 1 MB) zuweisen, sollte die Fragmentierung des Dateisystems verringert und die Leistung verbessert werden. Mozilla-Projekt ist currently using this setting in Firefox/Thunderbird mit great success.

In Bezug auf WAL. Wenn Sie so oft Daten schreiben, sollten Sie Ihre Schreibvorgänge in größere Transaktionen einschließen. Normalerweise wird jedes INSERT automatisch festgeschrieben, und SQLite muss warten, bis die Daten tatsächlich auf Festplatte oder Flash übertragen werden - was offensichtlich sehr langsam ist. Wenn Sie mehrere Schreibvorgänge in eine Transaktion einschließen, muss sich SQLite nicht um jede einzelne Zeile kümmern und viele Zeilen gleichzeitig löschen, höchstwahrscheinlich in einzelne Flash-Schreibvorgänge - was viel schneller ist. Also, wenn Sie können, versuchen Sie, mindestens ein paar hundert Schreibvorgänge in eine Transaktion zu wickeln.

Meiner Erfahrung nach funktioniert WAL auf Flash nicht sehr gut, und ich finde es günstiger, im alten Journaling-Modus zu bleiben. Zum Beispiel verwendet Android 4 den WAL-Modus für seine SQLite-Datenbanken nicht, und das aus einem bestimmten Grund. Wie Sie bemerkt haben, hat WAL eine Tendenz, ohne Schranke in einigen Situationen zu wachsen (aber wird es auch passieren, wenn Transaktionen selten begangen werden - so sicher sein, dass einmal in einer Weile zu tun).

+1

Beachten Sie, dass dies die Zuweisung von Dateibereich für die Datenbankdatei betrifft. Von dem, was ich Zuweisungen an die WAL-Datei verstehen ehrt nicht die Blockgröße. –

1

Im WAL-Modus schreibt SQLite geänderte Seiten in die Datei -wal. Nur während eines Prüfpunkts werden diese Seiten in die Datenbankdatei zurückgeschrieben. Die Datei -wal kann nur abgeschnitten werden, wenn keine parallelen Leser vorhanden sind.

Sie können versuchen, die WAL-Datei explizit zu bereinigen, indem Sie sqlite3_wal_checkpoint_v2 mit SQLITE_CHECKPOINT_RESTART aufrufen oder PRAGMA wal_checkpoint(RESTART) ausführen, aber dies schlägt fehl, wenn es gleichzeitige Leser gibt.

+0

Das scheint meine Frage nicht zu beantworten. –

Verwandte Themen